/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ora_ttc8_oall8.c                                   */
/*  NOTE      =                                                    */
/*  DATE      = 2014/10/21 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

#include "frmem.h"
#include "frcomm.h"
#include "frhash2.h"
#include "frlog.h"

#include "conntrack.h"
#include "frct_comm.h"
#include "frdb_cursor.h"

#include "../../ora_core.h"
#include "../../comm/ora_comm.h"
#include "../../comm/ora_stmt.h"
#include "../../comm/ora_util.h"
#include "../ora_mar_engine.h"
#include "../ora_ttc_proto.h"
#include "../sql/ora_NUMBER.h"
#include "../sql/ora_STRING.h"
#include "../sql/ora_TIMESTAMP.h"
#include "../accessor/ora_include_accessor.h"
#include "ora_ttc8_tti_rxh.h"
#include "ora_ttc8_tti_iov.h"
#include "ora_ttc8_tti_dcb.h"
#include "ora_ttc8_tti_oac.h"
#include "ora_ttc8_tti_rxd.h"
#include "ora_ttc8_oall8.h"
#include "../../comm/ora_charset.h"
#include "ora_ttc8_tti_oer.h"

/*******************************************************************************
*  FUNC     :  对应于T4C8Oclose的doOCANA()和doOCCA()方法
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_hash_report                    (数据上报)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_close_unpack(Conntrack *p_st_conn
                                , L7session_ora *p_st_sess
                                , L7_ora_packet *p_st_ora_packet
                                , Frhash_header *p_st_hash_report)
{
    ORA_PRINT_INFO("enter ora_ttc8_oall8_close_unpack\n");
    Sql_statement *p_st_stmt = NULL;
    char c_tmp = 0;
    short s_tmp = 0;
    int i_loop = 0;
    long long ll_offset = 0LL;
    long long ll_tmp = 0LL;
    long long ll_cursor = 0LL;

    uint64_t uint64_tmp = 0LL;
    int i_detect_count = 0;
    int i_change_typerep_count = 0;
    int i_need_detect = FR_NO;
    int i_start_detect_pos = 0;
    int i_change_typerep_pos = 0;
    int i_use_oci_old = p_st_sess->i_use_oci;
    int i_use_special_field_old = p_st_sess->i_use_special_field;
    int i_ptr_len_old = p_st_sess->i_ptr_len;
    int i_send_typerep_old = p_st_sess->i_send_typerep;
    char c_ttc_version_old = p_st_sess->c_ttc_version;
    Frlist_header *p_list_closed_cursors_tmp = NULL;
    Ora_cursor *p_st_ora_cursor = NULL;
    Frlist_node *p_st_node_cursor = NULL;
    long long ll_cursor_num = 0LL;
    unsigned long ul_cursor = 0L;

    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) == FR_FAIL) // seqNumber
        goto error;

    i_start_detect_pos = bytebuff_getPosition(p_st_ora_packet->p_st_packet);

detect_params:
    if (i_detect_count != 0 || p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET)
    {
        p_st_ora_packet->fragment_state = APM_ORA_FRAGMENT_INIT;
        if (i_use_oci_old != APM_ORA_FLAG_UNSET)
            goto error;
        else if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET)
        {
            p_st_sess->i_use_oci = FR_NO; // 假定为jdbc
            p_st_sess->i_send_typerep = FR_YES;
        }
        else if (p_st_sess->i_use_oci == FR_NO && p_st_sess->i_ptr_len == APM_ORA_FLAG_UNSET)
        {
            p_st_sess->i_use_oci = FR_YES; // 假定为oci
            p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_1;
            p_st_sess->i_send_typerep = APM_ORA_FLAG_UNSET;
        }
        else if (p_st_sess->i_use_oci == FR_NO && p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_1)
        {
            p_st_sess->i_use_oci = FR_YES; // 假定为oci
            p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_4;
            p_st_sess->i_send_typerep = APM_ORA_FLAG_UNSET;
        }
        else
            goto error;

        if (bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_start_detect_pos) != FR_SUCC)
            goto error;
        i_need_detect = FR_YES;

        if (i_detect_count >= 3)
            goto error;

        if (p_list_closed_cursors_tmp == NULL)
            p_list_closed_cursors_tmp = frlist_create();
        else
            frlist_remove_all(p_list_closed_cursors_tmp, frlist_node_data_free);
    }
    i_detect_count++;

    if (i_need_detect)
    {
        if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
            goto error;
        if (s_tmp != 0x01)
        {
            /**
             * 0x30a06702
             * 0xfe871a9e
             * 0xfeffffff
             * 0xfeffffff00000000
             * 0xf0922b0400000000
             * 0xfe922b0400000000
             * 0xfeffffffffffffff
             */
            p_st_sess->i_use_oci = FR_YES;
            p_st_sess->i_use_special_field = FR_YES;
            p_st_sess->i_send_typerep = APM_ORA_FLAG_UNSET;
#if APM_ORA_SUPPORT_OCI == 0
            i_use_special_field_old = FR_YES;
            goto error;
#endif
            if (s_tmp == 0xfe)
            {
                if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 3, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                if (uint64_tmp == 0xffffff)
                {
                    p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_4;
                    if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 7, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                        goto error;
                    if (uint64_tmp == 0xffffffffffffff || uint64_tmp == 0xffffff00000000) // 0xfeffffffffffffff or 0xfeffffff00000000
                    {
                        p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_8;
                        if (ora_mar_skip(p_st_ora_packet, 7) != FR_SUCC)
                            goto error;
                    }
                    else // 0xfeffffff
                    {
                        if (ora_mar_skip(p_st_ora_packet, 3) != FR_SUCC)
                            goto error;
                    }
                }
                else // 0xfe871a9e or 0xfe922b0400000000
                {
                    p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_4;
                    if (ora_mar_skip(p_st_ora_packet, 3) != FR_SUCC)
                        goto error;
                    if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                        goto error;
                    if (uint64_tmp == 0x00000000)
                    {
                        p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_8;
                        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                            goto error;
                    }
                }
            }
            else // 0x30a06702 or 0xf0922b0400000000
            {
                p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_4;
                if (ora_mar_skip(p_st_ora_packet, 3) != FR_SUCC)
                    goto error;
                if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                if (uint64_tmp == 0x00000000)
                {
                    p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_8;
                    if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                        goto error;
                }
            }
        }
        else if (p_st_sess->i_use_oci == FR_NO)
        {
            /**
             * 0x01
             */
            p_st_sess->i_use_special_field = FR_NO;
        }
        else if (p_st_sess->i_use_oci == FR_YES)
        {
            /**
             * 0x01
             * 0x01a04e02
             * 0x01a04e0200000000
             */
            p_st_sess->i_use_special_field = FR_YES;
#if APM_ORA_SUPPORT_OCI == 0
            i_use_special_field_old = FR_YES;
            goto error;
#endif
            if (p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_4)
            {
                if (ora_mar_skip(p_st_ora_packet, 3) != FR_SUCC)
                    goto error;
                if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                if (uint64_tmp == 0x00000000)
                {
                    p_st_sess->i_ptr_len = APM_ORA_PTR_LEN_8;
                    if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                        goto error;
                }
            }
        }

        i_change_typerep_count = 0;
        i_change_typerep_pos = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
change_typerep:
        if (i_change_typerep_count > 0)
        {
            if (p_st_sess->i_use_oci == FR_YES && p_st_sess->i_use_special_field == FR_YES)
            {
                p_st_sess->i_use_special_field = FR_NO;
                ora_set_ttc_type_rep_jdbc(p_st_sess);
                frlist_remove_all(p_list_closed_cursors_tmp, frlist_node_data_free);
                if (bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_change_typerep_pos) != FR_SUCC)
                    goto error;
            }
            else
                goto detect_params;
        }
        else
        {
            if (p_st_sess->i_use_oci == FR_YES && p_st_sess->i_use_special_field == FR_YES)
            {
                ora_set_ttc_type_rep(p_st_sess, 0, 0);
                ora_set_ttc_type_rep(p_st_sess, 1, 2);
                ora_set_ttc_type_rep(p_st_sess, 2, 2);
                ora_set_ttc_type_rep(p_st_sess, 3, 2);
                ora_set_ttc_type_rep(p_st_sess, 4, 0);
            }
            else
                ora_set_ttc_type_rep_jdbc(p_st_sess);
        }
        i_change_typerep_count++;

        if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_offset) != FR_SUCC || ll_offset <= 0 || ll_offset > 1000) // offset
            goto change_typerep;
        ll_cursor_num = ll_offset;

        if (p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_8)
        {
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)
                goto change_typerep;

            // ll_tmp为0时说明这个是skip字段，否则说明这个字段是游标值
            if (ll_tmp == 0LL)
            {
                p_st_sess->c_ttc_version = 4;
                p_st_sess->i_send_typerep = FR_NO;
                ORA_PRINT_DBG("has closed offset skip OCI4\n");
            }
            else
            {
                p_st_sess->i_send_typerep = FR_YES;
                if ((p_st_node_cursor = ora_create_closed_cursor_node((unsigned long) ll_tmp)) == NULL)
                    goto error;
                frlist_push(p_list_closed_cursors_tmp, p_st_node_cursor);
                ORA_PRINT_DBG("add first cursor:[%lld]\n", ll_tmp);
                ll_cursor_num = ll_offset - 1;
            }
        }

        // 将需要关闭的游标存到临时列表p_list_closed_cursors_tmp中
        for (i_loop = 0; i_loop < ll_cursor_num; i_loop++)
        {
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_cursor) != FR_SUCC) // cursorId
                goto change_typerep;
            if ((p_st_node_cursor = ora_create_closed_cursor_node((unsigned long) ll_cursor)) == NULL)
                goto error;
            ORA_PRINT_ERR("read cursor:[%lld] to close\n", ll_cursor);
            frlist_push(p_list_closed_cursors_tmp, p_st_node_cursor);
        }

        if (bytebuff_remaining(p_st_ora_packet->p_st_packet) > 0)
        {
            if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 2, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                goto change_typerep;
            switch (uint64_tmp)
            {
                case 0x030e:
                case 0x030f:
                case 0x033b:
                case 0x0347:
                case 0x035e:
                case 0x0360:
                case 0x1160:
                    break;
                default:
                    goto change_typerep;
            }
        }

        // 拷贝列表
        p_st_node_cursor = frlist_remove_head(p_list_closed_cursors_tmp);
        while (p_st_node_cursor)
        {
            p_st_ora_cursor = (Ora_cursor *) FRLIST_GET_NODE_DATA(p_st_node_cursor);
            ul_cursor = p_st_ora_cursor->ul_cursor;

            // 从关闭游标的列表中先清除该节点
            frlist_node_free(p_list_closed_cursors_tmp, p_st_node_cursor, 0, frlist_node_data_free);

            if ((p_st_stmt = ora_get_stmt(p_st_conn, (long) ul_cursor)) != NULL)
            {
                // 把要关闭的游标增加到list中
                if (ora_add_closed_cursor(p_st_sess, ul_cursor) != FR_SUCC)
                    goto error;

                // 设置l4层信息
                if (frdb_set_resultset_req(p_st_stmt, FRDB_LAST, 0, bytebuff_length(p_st_ora_packet->p_st_packet), &(p_st_ora_packet->st_timestamp_first), &(p_st_ora_packet->st_timestamp_last)) != FR_SUCC)
                    goto error;
            }
            else
                ORA_PRINT_WARN("can not find stmt of cursor:[%lu] to close\n", ul_cursor);

            p_st_node_cursor = frlist_remove_head(p_list_closed_cursors_tmp);
        }
    }
    else
    {
        if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR
            goto error;
        if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_offset) != FR_SUCC) // offset
            goto error;
        if (p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_NO && p_st_sess->c_ttc_version >= 4 && p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_8)
        {
            if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                goto error;
            ORA_PRINT_INFO("close skip OCI4\n");
        }

        // 将需要关闭的游标添加到session的p_list_closed_cursors列表中中去，在响应包中再取出这些游标
        for (i_loop = 0; i_loop < ll_offset; i_loop++)
        {
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_cursor) != FR_SUCC) // cursorId
                goto error;
            ORA_PRINT_ERR("read cursor:[%lld] to close\n", ll_cursor);

            if ((p_st_stmt = ora_get_stmt(p_st_conn, (long) ll_cursor)) != NULL)
            {
                // 把要关闭的游标增加到list中
                if (ora_add_closed_cursor(p_st_sess, (unsigned long) ll_cursor) != FR_SUCC)
                    goto error;

                // 设置l4层信息
                if (frdb_set_resultset_req(p_st_stmt, FRDB_LAST, 0, bytebuff_length(p_st_ora_packet->p_st_packet), &(p_st_ora_packet->st_timestamp_first), &(p_st_ora_packet->st_timestamp_last)) != FR_SUCC)
                    goto error;
            }
            else
                ORA_PRINT_WARN("can not find stmt of cursor:[%lld] to close\n", ll_cursor);
        }
    }

    frlist_destroy(p_list_closed_cursors_tmp, frlist_node_data_free);

    if (i_need_detect)
    {
        p_st_sess->i_c2snlsratio = 2;

        if (p_st_sess->i_use_oci == FR_NO)
        {
            // XXX: 大部分情况下是这样的
            p_st_sess->s_cli_charset_out = 871; // UTF8
            p_st_sess->s_srv_charset = 852; // ZHS16GBK
            p_st_sess->i_charset_assumed = FR_YES;
        }
        else
        {
            // XXX: 大部分情况下是这样的
            p_st_sess->s_cli_charset_out = 852; // ZHS16GBK
            p_st_sess->s_srv_charset = 852; // ZHS16GBK
            p_st_sess->i_charset_assumed = FR_YES;
        }

        ORA_PRINT_ALERT("set i_use_oci = %s, i_use_special_field = %s, i_send_typerep = %s, i_ptr_len = %d\n",
                        p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_use_oci == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_use_special_field == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_send_typerep == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_send_typerep == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ptr_len);
    }

    return FR_SUCC;
error:
    frlist_destroy(p_list_closed_cursors_tmp, frlist_node_data_free);
    p_st_sess->i_use_oci = i_use_oci_old;
    p_st_sess->i_use_special_field = i_use_special_field_old;
    p_st_sess->i_ptr_len = i_ptr_len_old;
    p_st_sess->i_send_typerep = i_send_typerep_old;
    p_st_sess->c_ttc_version = c_ttc_version_old;
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  对应于 ora12c oracle.jdbc.driver.T4CTTIoses void marshal() 方法
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_oses_unpack(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    short s_tmp = 0;
    long long ll_tmp = 0LL;

    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) == FR_FAIL) // seqNumber
        goto error;

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // sididx
        goto error;

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // sidser
        goto error;

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // sidopc
        goto error;

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  解析bind的值
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_stmt                           (Sql_statement)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_bind_unpack(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet
                            , Sql_statement *p_st_stmt
                            , Frhash_header *p_st_hash_report)
{
    ORA_PRINT_INFO("unmarshal bind data\n");

    short s_tmp = 0;
    int i_loop = 0;
    short s_bind_value_len = 0;
    char *p_bind_binary_value = NULL;
    char *p_bind_value = NULL;          // 存储字符串和数字类型
    int i_bind_value_len = 0;           // 字符串长度

    Sql_metadata_info *p_st_metadata = NULL;
    Frlist_node *p_st_node = NULL;
    Frlist_node *p_st_fiele_node = NULL;
    Sql_resultset *p_st_rs = NULL;
    Sql_field_bind *p_st_bind = NULL;
    Frdata_field *p_st_field = NULL;
    char *p_bind_index_name = NULL;
#if APM_ORA_DBG
    int i_pos_start = 0;
#endif

    if ((p_st_bind = (Sql_field_bind *) frmalloc(sizeof(Sql_field_bind))) == NULL)
    {
        ORA_MALLOCK_ERR;
        goto error;
    }
    memset(p_st_bind, 0x0, sizeof(Sql_field_bind));

    ORA_PRINT_CRIT("st_metadata_bind size:[%d]\n", frlist_size(&(p_st_stmt->st_metadata_bind)));
    p_st_node = FRLIST_FIRST_NODE(&(p_st_stmt->st_metadata_bind));
    while (p_st_node)
    {
        p_st_metadata = (Sql_metadata_info *) FRLIST_GET_NODE_DATA(p_st_node);
#if APM_ORA_DBG
        i_pos_start = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
#endif
        ORA_PRINT_INFO("unmarshal bind position %d\n", i_loop + 1);

        // 创建 Frdata_field
        if ((p_st_field = (Frdata_field *) frmalloc(sizeof(Frdata_field))) == NULL)
        {
            ORA_MALLOCK_ERR;
            goto error;
        }
        memset(p_st_field, 0x00, sizeof(Frdata_field));
        p_st_field->i_field_index = i_loop + 1;

        // 设置 Frdata_field 的 p_field_name
        if ((p_bind_index_name = (char *) frmalloc(APM_ORA_BIND_INDEX_NAME_MAXLEN * sizeof(char))) == NULL)
        {
            ORA_MALLOCK_ERR;
            goto error;
        }
        snprintf(p_bind_index_name, APM_ORA_BIND_INDEX_NAME_MAXLEN, "%s%d", APM_ORA_BIND_INDEX_NAME_PREFIX, i_loop);
        p_st_field->p_field_name = p_bind_index_name;
        p_bind_index_name = NULL;

        // em_data_type 默认设置为 FRSTRING
        p_st_field->em_data_type = FRSTRING;

        ORA_PRINT_CRIT("p_st_metadata => i_data_type:[%d] i_isnullbydescribe:[%s] i_isuseless:[%s]\n",
                p_st_metadata->i_data_type,
                FR_YESNO2STR(p_st_metadata->i_isnullbydescribe),
                FR_YESNO2STR(p_st_metadata->i_isuseless));

        ORA_PRINT_DTY_INFO((char *) "unmarshal bind data %s start\n", p_st_metadata->i_data_type);
        switch (p_st_metadata->i_data_type)
        {
            case ORA_DTY_VARCHAR:      // 1 0x01
            case ORA_DTY_LONG:         // 8 0x08
            case ORA_DTY_CHAR:         // 96 0x60
            case ORA_DTY_ROWID2:
            case ORA_DTY_ROWID:        // 104 0x68
            case ORA_DTY_UROWID:
                p_st_field->em_data_type = FRSTRING;
                if (p_st_metadata->s_ora_oacflg == 0x07)
                {
                    p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                }
                else
                {
                    if (ora_mar_peekUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
                        goto error;
                    if (s_tmp == 0xFD)
                    {
                        if (ora_mar_skip(p_st_ora_packet, 2) != FR_SUCC)
                            goto error;
                        p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    }
                    else if (s_tmp == 0x00 || s_tmp == 0xFF)
                    {
                        if (ora_mar_skip(p_st_ora_packet, 1) != FR_SUCC)
                            goto error;
                        if (p_st_sess->i_use_special_field == FR_YES && ora_mar_skip(p_st_ora_packet, 3) != FR_SUCC)
                            goto error;
                        p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    }
                    else
                    {
                        if (ora_mar_unmarshalCLRforREFS(p_st_sess, p_st_ora_packet, &p_bind_binary_value, &i_bind_value_len) != FR_SUCC)
                            goto error;

                        if (ora_STRING_toChar(p_bind_binary_value, (size_t) i_bind_value_len, &p_bind_value, &i_bind_value_len) != FR_SUCC)
                            goto error;
						
                        if (p_bind_value != NULL)
                            p_st_field->p_field_value = (char *) frmemdup(p_bind_value, (size_t) i_bind_value_len + 1);
                        else
                            p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    }
                }
                break;

            case ORA_DTY_NUMBER:       // 2 0x02
            case ORA_DTY_VARNUM:       // 6 0x06
                // XXX: 校准这里的em_data_type，有可能为FRINT/FRLONG/FRFLOAT/FRDOUBLE
                p_st_field->em_data_type = FRDOUBLE;
                if (p_st_metadata->s_ora_oacflg == 0x07)
                {
                    p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                }
                else
                {
                    // bind数据的字节数长度
                    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_bind_value_len) != FR_SUCC)
                        goto error;
                    if (s_bind_value_len == 0x00)
                        p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    else if (s_bind_value_len == 0xfd)
                    {
                        if (ora_mar_skip(p_st_ora_packet, 1) != FR_SUCC)
                            goto error;
                        p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    }
                    else
                    {
                        // 将要解析的数据拷贝到 p_bind_binary_value 中去
                        if ((p_bind_binary_value = (char *) ora_malloc(s_bind_value_len * sizeof(char), bytebuff_remaining(p_st_ora_packet->p_st_packet))) == NULL)
                        {
                            ORA_MALLOCK_ERR;
                            goto error;
                        }
                        if (bytebuff_get_bytes(p_st_ora_packet->p_st_packet, p_bind_binary_value, (unsigned int) s_bind_value_len) != FR_SUCC)
                            goto error;

                        if (ora_NUMBER_toChar(p_bind_binary_value, (size_t) s_bind_value_len, &p_bind_value, &i_bind_value_len) != FR_SUCC)
                            goto error;

                        if (p_bind_value != NULL)
                            p_st_field->p_field_value = (char *) frmemdup(p_bind_value, (size_t) i_bind_value_len + 1);
                        else
                            p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    }
                }
                break;

            case ORA_DTY_DATE:          // 12 0x0c
            case ORA_DTY_TIMESTAMP:    // 180 0xb4
                p_st_field->em_data_type = FRTIME;
                if (p_st_metadata->s_ora_oacflg == 0x07)
                {
                    p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                }
                else
                {
                    // bind数据的字节数长度
                    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_bind_value_len) != FR_SUCC)
                        goto error;
                    if (s_bind_value_len == 0x00)
                        p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    else if (s_bind_value_len == 0xfd)
                    {
                        if (ora_mar_skip(p_st_ora_packet, 1) != FR_SUCC)
                            goto error;
                        p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    }
                    else
                    {
                        // 将要解析的数据拷贝到 p_bind_binary_value 中去
                        if ((p_bind_binary_value = (char *) ora_malloc(s_bind_value_len * sizeof(char), bytebuff_remaining(p_st_ora_packet->p_st_packet))) == NULL)
                        {
                            ORA_MALLOCK_ERR;
                            goto error;
                        }
                        if (bytebuff_get_bytes(p_st_ora_packet->p_st_packet, p_bind_binary_value, (unsigned int) s_bind_value_len) != FR_SUCC)
                            goto error;

                        if (ora_TIMESTAMP_toLongLong(p_bind_binary_value, (size_t) s_bind_value_len, &p_bind_value) != FR_SUCC)
                            goto error;
                        if (p_bind_value != NULL)
                            p_st_field->p_field_value = frstrdup(p_bind_value);
                        else
                            p_st_field->p_field_value = frstrdup(APM_ORA_BIND_NULL);
                    }
                }
                break;

            case ORA_DTY_RAW:          // 23 0x17
                p_st_field->em_data_type = FRBLOB;
                if (ora_raw_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                p_st_field->p_field_value = frstrdup(APM_ORA_BIND_BLOB);
                break;

            case ORA_DTY_LONG_RAW:     // 24 0x18
                p_st_field->em_data_type = FRBLOB;
                if (ora_longraw_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                p_st_field->p_field_value = frstrdup(APM_ORA_BIND_BLOB);
                break;

            case ORA_DTY_BINARY_FLOAT:// 100 0x64
                p_st_field->em_data_type = FRBLOB;
                if (ora_binaryfloat_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                p_st_field->p_field_value = frstrdup(APM_ORA_BIND_BLOB);
                break;

            case ORA_DTY_BINARY_DOUBLE:// 101 0x65
                p_st_field->em_data_type = FRBLOB;
                if (ora_binarydouble_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                p_st_field->p_field_value = frstrdup(APM_ORA_BIND_BLOB);
                break;

            case ORA_DTY_RESULT_SET:   // 102 0x66
                if (ora_resultset_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_NAMED_TYPE:   // 109 0x6d
            case ORA_DTY_NAMED_TYPE2:  // 121 0x79
                if (ora_namedtype_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_REF_TYPE:     // 111 0x6f
                if (ora_reftype_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_CLOB:         // 112 0x70
                p_st_field->em_data_type = FRCLOB;
                if (ora_clob_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_stmt->ll_ora_options, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_BLOB:         // 113 0x71
                p_st_field->em_data_type = FRBLOB;
                if (ora_blob_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_BFILE:        // 114 0x72
                p_st_field->em_data_type = FRBLOB;
                if (ora_bfile_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_stmt->ll_ora_options, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_TIMESTAMPTZ:  // 181 0xb5
                if (ora_timestamptz_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_INTERVALYM:   // 182 0xb6
                if (ora_intervalym_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_INTERVALDS:   // 183 0xb7
                if (ora_intervalds_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            case ORA_DTY_TIMESTAMPLTZ: // 231 0xe7
                if (ora_timestampltz_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                    goto error;
                break;

            default:
                break;
        }
        ORA_PRINT_WARN("p_st_field->p_field_value:[%s]\n", p_st_field->p_field_value);
        ORA_PRINT_DTY_INFO((char *) "unmarshal bind data %s done\n", p_st_metadata->i_data_type);

        ora_free((void **) &p_bind_value);
        ora_free((void **) &p_bind_binary_value);

#if APM_ORA_DBG
        ORA_PRINT_PACKET_SPECIFIED("unmarshaled one row", p_st_ora_packet, i_pos_start, bytebuff_getPosition(p_st_ora_packet->p_st_packet) - i_pos_start);
#endif

        p_st_fiele_node = frlist_node_create(p_st_field);
        frlist_push(&(p_st_bind->st_field_list), p_st_fiele_node);
        i_loop++;
        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }

    if ((p_st_rs = frdb_get_last_resultset(p_st_stmt)) == NULL)
        goto error;
    if (frdb_add_resultset_bind(p_st_rs, p_st_bind) != FR_SUCC)
        goto error;
    p_st_bind = NULL;

    ORA_PRINT_INFO("leave ora_ttc8_oall8_bind_unpack\n");

    return FR_SUCC;
error:
    frdb_field_bind_free(&p_st_bind);
    ora_free((void **) &p_bind_index_name);
    ora_free((void **) &p_bind_value);
    ora_free((void **) &p_bind_binary_value);
    ora_frdata_free(&p_st_field);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  解析0x0305的fetch请求包
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_unpack_fetch_req(Conntrack *p_st_conn
                                    , L7session_ora *p_st_sess
                                    , L7_ora_packet *p_st_ora_packet)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    Sql_statement *p_st_stmt = NULL;
    short s_tmp = 0;
    int i_tmp = 0;
    unsigned long ul_curr_cursor = 0L;

    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC) // seqNumber
        goto error;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // cursor
        goto error;
    ul_curr_cursor = (unsigned long) i_tmp;

    if ((p_st_stmt = ora_get_stmt(p_st_conn, ul_curr_cursor)) == NULL)
    {
        ORA_PRINT_EMERG("can not find current cursor:[%lu]\n", ul_curr_cursor);
        goto error;
    }
    p_st_curr_sess->ul_cursor = ul_curr_cursor;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // al8i4[1] 要fetch的条数
        goto error;

    // 设置l4层信息
    if (frdb_set_resultset_req(p_st_stmt, FRDB_LAST, 0, bytebuff_length(p_st_ora_packet->p_st_packet), &(p_st_ora_packet->st_timestamp_first), &(p_st_ora_packet->st_timestamp_last)) != FR_SUCC)
        goto error;

    return FR_SUCC;
error:
    return FR_FAIL;
}

FR_STATIC int __ora_ttc8_oall8_analyze_req_jdbc(Conntrack *p_st_conn
                                                , L7session_ora *p_st_sess
                                                , L7_ora_packet *p_st_ora_packet)
{
    ORA_PRINT_FATAL("enter __ora_ttc8_oall8_analyze_req_jdbc\n");
    char c_tmp = 0;
    char c_sql_flag = 0;
    char c_al8i4_flag = 0;
    char c_ptr1 = 0;
    char c_ptr2 = 0;
    short s_tmp = 0;
    int i_tmp = 0;
    int i_cursor = 0;
    int i_sql_len = 0;
    int i_al8i4_len = 0;
    int i_analyze_start_pos1 = 0;
    int i_analyze_start_pos2 = 0;
    int i_analyze_start_pos3 = 0;
    long long ll_tmp = 0LL;
    long long ll_tmp1 = 0LL;
    long long ll_tmp2 = 0LL;
    long long ll_options = 0LL;
    char *p_tmp = NULL;
    char arr_sql_head[10] = {'\0'};

    int i_ttc8_stmt_req_i_old = p_st_sess->i_ttc8_stmt_req_i;
    int i_ttc8_stmt_req_j_old = p_st_sess->i_ttc8_stmt_req_j;
    int i_ttc8_stmt_req_dml_old = p_st_sess->i_ttc8_stmt_req_dml;
    int i_CHR_conversion_flags_old = p_st_sess->i_CHR_conversion_flags;
    int i_useCLR_big_chunks_old = p_st_sess->i_useCLR_big_chunks;
    p_st_sess->i_ttc8_long_analyze_succ = FR_NO;

    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)                                       // seqNumber
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_options) != FR_SUCC)                       // options
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_cursor) != FR_SUCC)                       // cursor
        goto error;
    // 使用新创建的statement请求进行判断
    if (i_cursor != 0)
    {
        ORA_PRINT_DBG("cursor:[%d], not 0\n", i_cursor);
        goto error;
    }
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_sql_flag) != FR_SUCC)                       // sqlStmt.flag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_sql_len) != FR_SUCC)                      // sqlStmt.length
        goto error;
    // 需要存在sql语句的情况下进行判断
    if (c_sql_flag == APM_ORA_NULLPTR || i_sql_len <= 0)
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_al8i4_flag) != FR_SUCC)                     // al8i4.flag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_al8i4_len) != FR_SUCC)                    // al8i4.length
        goto error;
    // 目前的测试情况来看，从8.1.7.0到12.1.0.2，al8i4.flag为PTR，al8i4.length不大于0x0d
    if (c_al8i4_flag == APM_ORA_NULLPTR || i_al8i4_len > 0x0d)
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // NULLPTR or PTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // NULLPTR or PTR
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)                           // Long.MAX_VALUE
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)                           // rowsToFetch
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)                           // isPlsqlOrCall
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // bindFlag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)                          // numberOfBindPositions
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    // XXX: 应要注意这里的defCols的定义在ttc>=2时才会，目前8i开始的版本ttc应该均大于2，所以这里将这个条件去掉了
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // defColsFlag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)                          // defCols
        goto error;
    if (p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET ||
            p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET ||
            p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET)
    {
        i_analyze_start_pos1 = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
        if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) == FR_SUCC)                           // i
        {
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr1) == FR_SUCC && // NULLPTR for jdbc / NULLPTR OR PTR for oci
                    ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr2) == FR_SUCC // PTR
                && ((p_st_sess->i_use_oci == FR_NO && c_ptr1 != APM_ORA_NULLPTR && c_ptr2 != APM_ORA_PTR) || (p_st_sess->i_use_oci == FR_YES && c_ptr2 != APM_ORA_PTR)))
            {
                bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos1);
                p_st_sess->i_ttc8_stmt_req_i = FR_NO;
                p_st_sess->i_ttc8_stmt_req_j = FR_NO;
                p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
            }
            else
            {
                p_st_sess->i_ttc8_stmt_req_i = FR_YES;

                i_analyze_start_pos2 = bytebuff_getPosition(p_st_ora_packet->p_st_packet);

                // i_ttc8_stmt_req_j为FR_YES的话，这里应该是 NULLPTR + UB4(0) + NULLPTR + UB4(0) + UB4(j)
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr1) == FR_SUCC &&                     // NULLPTR
                    ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp1) == FR_SUCC &&                    // UB4(0)
                    ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr2) == FR_SUCC &&                     // NULLPTR
                    ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp2) == FR_SUCC &&                    // UB4(0)
                        c_ptr1 == APM_ORA_NULLPTR && ll_tmp1 == 0 && c_ptr2 == APM_ORA_NULLPTR && ll_tmp2 == 0)
                {
                    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)                   // j
                        goto error;
                    p_st_sess->i_ttc8_stmt_req_j = FR_YES;

                    i_analyze_start_pos3 = bytebuff_getPosition(p_st_ora_packet->p_st_packet);

                    // i_ttc8_stmt_req_dml为FR_YES的话，这里应该是 NULLPTR + UB4(0) + NULLPTR 或者 PTR + UB4 + PTR
                    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr1) == FR_SUCC &&
                            ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) == FR_SUCC &&
                            ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr2) == FR_SUCC &&
                            ((c_ptr1 == APM_ORA_NULLPTR && ll_tmp == 0LL && c_ptr2 == APM_ORA_NULLPTR) ||
                                (c_ptr1 == APM_ORA_PTR && c_ptr2 == APM_ORA_PTR))) // PTR or NULLPTR | currentRank | PTR or NULLPTR
                        p_st_sess->i_ttc8_stmt_req_dml = FR_YES;
                    else
                    {
                        bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos3);
                        p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
                    }
                }
                else
                {
                    bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos2);
                    p_st_sess->i_ttc8_stmt_req_j = FR_NO;
                    p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
                }
            }
        }
        else
        {
            bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos1);
            p_st_sess->i_ttc8_stmt_req_i = FR_NO;
            p_st_sess->i_ttc8_stmt_req_j = FR_NO;
            p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
        }

        ORA_PRINT_DBG("set i_ttc8_stmt_req_i = %s, i_ttc8_stmt_req_j = %s, i_ttc8_stmt_req_dml = %s\n",
                      p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_req_i == FR_YES ? "FR_YES" : "FR_NO"),
                      p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_req_j == FR_YES ? "FR_YES" : "FR_NO"),
                      p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_req_dml == FR_YES ? "FR_YES" : "FR_NO"));
    }
    else
    {
        if (p_st_sess->i_ttc8_stmt_req_i == FR_YES)
        {
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // i
                goto error;
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // 1个NULLPTR
                goto error;
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR
                goto error;
            if (p_st_sess->i_ttc8_stmt_req_j == FR_YES)
            {
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // 1个NULLPTR
                    goto error;
                if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // 0L
                    goto error;
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // 1个NULLPTR
                    goto error;
                if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // 0L
                    goto error;
                if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // j
                    goto error;
                if (p_st_sess->i_ttc8_stmt_req_dml == FR_YES)
                {
                    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
                        goto error;
                    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // currentRank
                        goto error;
                    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
                        goto error;
                }
            }
        }
    }

    if (p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET || (p_st_sess->i_CHR_conversion_flags == FR_YES && p_st_sess->i_useCLR_big_chunks == APM_ORA_FLAG_UNSET))
    {
        if (p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
        {
            if (bytebuff_remaining(p_st_ora_packet->p_st_packet) < 10)
                goto error;
            if (bytebuff_peek_bytes(p_st_ora_packet->p_st_packet, arr_sql_head, 10) != FR_SUCC)
                goto error;
            if (ora_is_sql(arr_sql_head, 10) == FR_SUCC)
                p_st_sess->i_CHR_conversion_flags = FR_NO;
            else
                p_st_sess->i_CHR_conversion_flags = FR_YES;
        }

        if (p_st_sess->i_CHR_conversion_flags == FR_YES && p_st_sess->i_useCLR_big_chunks == APM_ORA_FLAG_UNSET)
        {
            int i_ret = 0;
            if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
                goto error;
            if (ora_mar_escapeSequenceNull(s_tmp, &i_ret) != FR_SUCC)
                goto error;
            if (i_ret != 1 && s_tmp == 0xfe)
            {
                if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
                    goto error;
                p_st_sess->i_useCLR_big_chunks = s_tmp <= 4 ? FR_YES : FR_NO;
                if (bytebuffer_backspace(p_st_ora_packet->p_st_packet, 1) != FR_SUCC)
                    goto error;
            }
            if (bytebuffer_backspace(p_st_ora_packet->p_st_packet, 1) != FR_SUCC)
                goto error;
        }

        ORA_PRINT_DBG("set i_CHR_conversion_flags = %s, i_useCLR_big_chunks = %s\n",
                      p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_CHR_conversion_flags == FR_YES ? "FR_YES" : "FR_NO"),
                      p_st_sess->i_useCLR_big_chunks == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_useCLR_big_chunks == FR_YES ? "FR_YES" : "FR_NO"));
    }

    if (ora_mar_unmarshalCHR(i_sql_len, p_st_sess, p_st_ora_packet, &p_tmp, &i_tmp) == FR_SUCC) // sqlStmt
    {
        if (ora_is_sql(p_tmp, i_tmp) != FR_SUCC)
        {
            ora_free((void **) &p_tmp);
            goto error;
        }
        if (ora_is_sql_select(p_tmp, i_tmp) != FR_SUCC)
        {
            ora_free((void **) &p_tmp);
            ORA_PRINT_DBG("is not select sql\n");
            i_CHR_conversion_flags_old = p_st_sess->i_CHR_conversion_flags;
            i_useCLR_big_chunks_old = p_st_sess->i_useCLR_big_chunks;
            goto error;
        }
        ora_free((void **) &p_tmp);
    }
    else
        goto error;

    if (ora_mar_unmarshalUB4Array(i_al8i4_len, p_st_sess, p_st_ora_packet) != FR_SUCC) // al8i4
        goto error;

    p_st_sess->i_ttc8_stmt_resp_rpadml = p_st_sess->i_ttc8_stmt_req_dml;

    return FR_SUCC;
error:
    p_st_ora_packet->fragment_state = APM_ORA_FRAGMENT_INIT;
    p_st_sess->i_ttc8_stmt_req_i = i_ttc8_stmt_req_i_old;
    p_st_sess->i_ttc8_stmt_req_j = i_ttc8_stmt_req_j_old;
    p_st_sess->i_ttc8_stmt_req_dml = i_ttc8_stmt_req_dml_old;
    p_st_sess->i_CHR_conversion_flags = i_CHR_conversion_flags_old;
    p_st_sess->i_useCLR_big_chunks = i_useCLR_big_chunks_old;
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  解析0x035E的sql请求包
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_hash_report                    (数据上报)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ora_ttc8_oall8_unpack_req_jdbc(Conntrack *p_st_conn
                                            , L7session_ora *p_st_sess
                                            , L7_ora_packet *p_st_ora_packet
                                            , Frhash_header *p_st_hash_report)
{
    ORA_PRINT_INFO("enter __ora_ttc8_oall8_unpack_req_jdbc\n");
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    Sql_statement *p_st_stmt = NULL;
    Sql_resultset *p_st_rs = NULL;

    int i_tmp = 0;
    char *p_tmp = NULL;

    long long ll_options = 0LL;
    unsigned long ul_curr_cursor = 0L;
    int i_sql_len = 0;
    int i_al8i4_len = 0;
    char *p_sql = NULL;
    unsigned int ui_sql_utf8_len = 0;
    int i_loop = 0;
    int i_defCols_len = 0;
    int i_numberOfBindPositions_len = 0;
    int i_report_stmt_req = FR_NO;
    int i_sql_exists = FR_NO;
    int i_reported_last_resp = FR_NO;
    int i_set_sql = FR_NO;
    int i_set_metadata_bind = FR_NO;
    int i_set_metadata_define = FR_NO;
    int i_set_bind_value = FR_NO;

    if (ora_mar_skipUB1(p_st_ora_packet) != FR_SUCC) // seqNumber
        goto error;

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_options) != FR_SUCC) // options
        goto error;
    // TODO: 判断autocommit

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // cursor
        goto error;

    /**
    * 发送sql请求时的cursor，如果为0，表示当前是一个新的statement，客户端会使用服务端返回的另外一个cursor执行同一个statement请求
    * 所以cursor为0时，需要新建一个 Ora_statement，
    */
    ul_curr_cursor = (unsigned long) i_tmp;
    if (ul_curr_cursor == 0L)
    {
        // 新建一个游标为0的 Sql_statement
        if (ora_set_new_stmt(p_st_conn, &p_st_stmt) != FR_SUCC)
            goto error;
        ORA_PRINT_DBG("create new stmt of cursor:[0]\n");
    }
    else
    {
        // 从当前的列表中根据 cursor 获取 Ora_statement
        if ((p_st_stmt = ora_get_stmt(p_st_conn, ul_curr_cursor)) == NULL)
        {
            if (ora_set_new_stmt(p_st_conn, &p_st_stmt) != FR_SUCC)
                goto error;
            p_st_stmt->l_cursor_id = ul_curr_cursor;
            ORA_PRINT_DBG("create new stmt of cursor:[%ld]\n", p_st_stmt->l_cursor_id);
        }
    }
    p_st_curr_sess->ul_cursor = ul_curr_cursor;

    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // sqlStmt.flag
        goto error;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_sql_len) != FR_SUCC) // sqlStmt.length
        goto error;

    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // al8i4.flag
        goto error;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_al8i4_len) != FR_SUCC) // al8i4.length
        goto error;

    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // NULLPTR or PTR
        goto error;
    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // NULLPTR or PTR
        goto error;

    if (ora_mar_skipUB4(p_st_sess, p_st_ora_packet) != FR_SUCC) // Long.MAX_VALUE
        goto error;

    if (ora_mar_skipUB4(p_st_sess, p_st_ora_packet) != FR_SUCC) // rowsToFetch
        goto error;

    if (ora_mar_skipUB4(p_st_sess, p_st_ora_packet) != FR_SUCC) // isPlsqlOrCall
        goto error;

    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // bindFlag
        goto error;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_numberOfBindPositions_len) != FR_SUCC) // numberOfBindPositions
        goto error;

//    if (ora_mar_skip(p_st_ora_packet, 5) != FR_SUCC) // 5个NULLPTR
//        goto error;
    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // PTR or NULLPTR
        goto error;
    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // PTR or NULLPTR
        goto error;
    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // PTR or NULLPTR
        goto error;
    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // PTR or NULLPTR
        goto error;
    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // PTR or NULLPTR
        goto error;

    // p_st_sess->c_ttc_version >= 2
    if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // defColsFlag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_defCols_len) != FR_SUCC) // defCols
        goto error;

    if (p_st_sess->i_ttc8_stmt_req_i == FR_YES) // (p_st_sess->s_tns_version >= 308 && p_st_sess->c_ttc_version >= 4 && p_st_sess->s_CTcap_len >= 5 && p_st_sess->p_CTcap[4] >= 8)
    {
        if (ora_mar_skipUB4(p_st_sess, p_st_ora_packet) != FR_SUCC) // i
            goto error;
        if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // 1个NULLPTR
            goto error;
        if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // PTR
            goto error;

        ORA_PRINT_NOTICE("unmarshaled i PTR PTR\n");

        if (p_st_sess->i_ttc8_stmt_req_j == FR_YES) // p_st_sess->c_ttc_version >= 5
        {
            if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // 1个NULLPTR
                goto error;
            if (ora_mar_skipUB4(p_st_sess, p_st_ora_packet) != FR_SUCC) // 0L
                goto error;
            if (ora_mar_skipO2U(p_st_sess, p_st_ora_packet) != FR_SUCC) // 1个NULLPTR
                goto error;
            if (ora_mar_skipUB4(p_st_sess, p_st_ora_packet) != FR_SUCC) // 0L
                goto error;
            if (ora_mar_skipUB4(p_st_sess, p_st_ora_packet) != FR_SUCC) // j
                goto error;

            ORA_PRINT_NOTICE("unmarshaled PTR 0L PTR 0L j\n");

            if (p_st_sess->i_ttc8_stmt_req_dml == FR_YES) // p_st_sess->c_ttc_version >= 7
            {
                char c_ptr_flag1 = 0;
                char c_ptr_flag2 = 0;
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr_flag1) != FR_SUCC) // PTR or NULLPTR
                    goto error;
                if (ora_mar_skipUB4(p_st_sess, p_st_ora_packet) != FR_SUCC) // currentRank
                    goto error;
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr_flag2) != FR_SUCC) // PTR or NULLPTR
                    goto error;
                if (c_ptr_flag1 == APM_ORA_PTR && c_ptr_flag2 == APM_ORA_PTR)
                    p_st_stmt->i_is_dml = FR_YES;
                else
                    p_st_stmt->i_is_dml = FR_NO;
                ORA_PRINT_DBG("set p_st_stmt->i_is_dml = %s\n", p_st_stmt->i_is_dml == FR_YES ? "FR_YES" : "FR_NO");
                ORA_PRINT_NOTICE("unmarshaled PTR currentRank PTR\n");
            }
        }
    }

    if (p_st_stmt->p_sql != NULL)
        i_sql_exists = FR_YES;

    if (i_sql_len > 0)
    {
        ORA_PRINT_DBG("i_sql_len:[%d]\n", i_sql_len);
        if (ora_mar_unmarshalCHR(i_sql_len, p_st_sess, p_st_ora_packet, &p_tmp, &i_tmp) == FR_SUCC) // sqlStmt
        {
            if (p_tmp != NULL)
            {
                if (ora_str_to_utf8(p_st_sess, p_st_sess->s_cli_charset_out, p_tmp, (unsigned int) i_tmp, &p_sql, &ui_sql_utf8_len) != FR_SUCC)
                    goto error;

                // 如果stmt中已存在sql的话，则先上报之前的信息
                if (i_sql_exists == FR_YES)
                {
                    if (ora_report_stmt_resp(p_st_conn, p_st_sess, p_st_stmt, p_st_hash_report, FR_YES) != FR_SUCC)
                        goto error;
                    i_reported_last_resp = FR_YES;
                }

                ORA_PRINT_WARN("sql before delete comments:[%s]\n", p_sql);
                ora_sql_delete_comments(&p_sql);
                frdb_reset_sql(p_st_stmt, p_sql);
                i_set_sql = FR_YES;
                i_report_stmt_req = FR_YES;
                ORA_PRINT_ERR("sql after delete comments:[%s]\n", p_sql);
                p_sql = NULL;
            }
            ora_free((void **) &p_tmp);
        }
        else
            goto error;
    }

    if (ora_mar_unmarshalUB4Array(i_al8i4_len, p_st_sess, p_st_ora_packet) != FR_SUCC) // al8i4
        goto error;

    p_st_stmt->ll_ora_options = ll_options;
    ORA_PRINT_DBG("ll_options:[%lld], i_numberOfBindPositions_len:[%d], i_defCols_len:[%d]\n", ll_options, i_numberOfBindPositions_len, i_defCols_len);
    if ((ll_options & 0x8) != 0LL && i_numberOfBindPositions_len > 0)
    {
        ORA_PRINT_INFO("unmarshal bind dty\n");
        frlist_remove_all(&(p_st_stmt->st_metadata_bind), frdb_metadata_node_free);
        for (i_loop = 0; i_loop < i_numberOfBindPositions_len; i_loop++)
        {
            if (ora_ttc8_tti_oac_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet, APM_ORA_OACTYPE_BIND, p_st_stmt) != FR_SUCC)
                goto error;
            i_set_metadata_bind = FR_YES;
        }
    }

    // 不支持c_ttc_version<2的版本
    if ((ll_options & 0x10) != 0LL)
    {
        ORA_PRINT_INFO("unmarshal definition dty\n");
        frlist_remove_all(&(p_st_stmt->st_metadata_define), frdb_metadata_node_free);
        for (i_loop = 0; i_loop < i_defCols_len; i_loop++)
        {
            if (ora_ttc8_tti_oac_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet, APM_ORA_OACTYPE_DEFINE, p_st_stmt) != FR_SUCC)
                goto error;
            i_set_metadata_define = FR_YES;
        }
    }

    if ((ll_options & 0x20) != 0LL && i_numberOfBindPositions_len > 0)
    {
        // 解析bind值
        ORA_PRINT_INFO("unmarshal bind value\n");
        if (i_sql_exists == FR_YES && i_reported_last_resp == FR_NO)
        {
            if (ora_report_stmt_resp(p_st_conn, p_st_sess, p_st_stmt, p_st_hash_report, FR_YES) != FR_SUCC)
                goto error;
        }
        if ((p_st_rs = frdb_get_last_resultset(p_st_stmt)) == NULL)
            goto error;
        frlist_remove_all(&(p_st_rs->st_bind_list), frdb_field_bind_node_free);
        short s_ttc_code;
        while (bytebuff_remaining(p_st_ora_packet->p_st_packet) > 0)
        {
            i_report_stmt_req = FR_YES;
            if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_ttc_code) != FR_SUCC)
                goto error;
            if (s_ttc_code != APM_TTC_CODE_TTIRXD)
                goto error;
            if (ora_ttc8_oall8_bind_unpack(p_st_conn, p_st_sess, p_st_ora_packet, p_st_stmt, p_st_hash_report) != FR_SUCC)
                goto error;
            i_set_bind_value = FR_YES;

            /**
             * XXX: 从wasu抓到的包中发现在bind结束后还跟了一串xml,下面主要用来判断这种情况,如果遇到,则直接跳过
             */
            if (bytebuff_remaining(p_st_ora_packet->p_st_packet) > 10)
            {
                char arr_remaining_tmp[10] = {0};
                if (bytebuff_peek_bytes(p_st_ora_packet->p_st_packet, arr_remaining_tmp, 10) != FR_SUCC)
                    goto error;
                /**
                 * 对应四种情况,其中fe40开头是长字符串的意思
                 * 1. <?xml ve
                 * 2. CRLF<root>
                 * 3. LF<root>
                 * 4. CR<root>
                 */
                if (memcmp(arr_remaining_tmp, "\xfe\x40\x3c\x3f\x78\x6d\x6c\x20\x76\x65", 10) == 0 ||
                    memcmp(arr_remaining_tmp, "\xfe\x40\x0d\x0a\x3c\x72\x6f\x6f\x74\x3e", 10) == 0 ||
                    memcmp(arr_remaining_tmp, "\xfe\x40\x0a\x3c\x72\x6f\x6f\x74\x3e", 9) == 0 ||
                    memcmp(arr_remaining_tmp, "\xfe\x40\x0d\x3c\x72\x6f\x6f\x74\x3e", 9) == 0)
                {
                    ORA_PRINT_EMERG("detect abnormal bytes and skip bytes of length:[0x%04x]\n", bytebuff_remaining(p_st_ora_packet->p_st_packet));
                    bytebuff_setPositionEnd(p_st_ora_packet->p_st_packet);
                    break;
                }
            }
        }
    }

    // 设置l4层信息
    if (frdb_set_resultset_req(p_st_stmt, FRDB_LAST, 0, bytebuff_length(p_st_ora_packet->p_st_packet), &(p_st_ora_packet->st_timestamp_first), &(p_st_ora_packet->st_timestamp_last)) != FR_SUCC)
        goto error;

    // 数据上报
    if (i_report_stmt_req == FR_YES && ora_report_stmt_req(p_st_conn, p_st_sess, p_st_stmt, p_st_hash_report) != FR_SUCC)
        goto error;

    return FR_SUCC;
error:
    ora_free((void **) &p_tmp);
    if (ora_packet_is_in_fragment(p_st_ora_packet) && ul_curr_cursor != 0L)
    {
        if (i_set_sql)
            ora_free((void **) &(p_st_stmt->p_sql));
        if (i_set_metadata_bind)
            frlist_remove_all(&(p_st_stmt->st_metadata_bind), frdb_metadata_node_free);
        if (i_set_metadata_define)
            frlist_remove_all(&(p_st_stmt->st_metadata_define), frdb_metadata_node_free);
        if (i_set_bind_value)
            frlist_remove_all(&(p_st_rs->st_bind_list), frdb_field_bind_node_free);
    }
    else
    {
        if (ul_curr_cursor == 0L)
            frdb_statement_free(&(p_st_session_private->p_st_req->p_st_stmt));
        ora_free((void **) &p_sql);
    }
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  分析0x035E的sql请求包
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ora_ttc8_oall8_analyze_req_oci(Conntrack *p_st_conn
                                                , L7session_ora *p_st_sess
                                                , L7_ora_packet *p_st_ora_packet)
{
    ORA_PRINT_FATAL("enter __ora_ttc8_oall8_analyze_req_oci\n");
    char c_tmp = 0;
    char c_ptr1 = 0;
    char c_ptr2 = 0;
    char c_sql_flag = 0;
    char c_al8i4_flag = 0;
    short s_tmp = 0;
    int i_tmp = 0;
    int i_cursor = 0;
    long long ll_tmp = 0LL;
    char *p_tmp = NULL;
    long long ll_options = 0LL;
    int i_sql_len = 0;
    int i_al8i4_len = 0;
    uint64_t uint64_tmp = 0LL;
    char arr_sql_head[10] = {'\0'};

    int i_analyze_start_pos1 = 0;
    int i_analyze_start_pos2 = 0;
    int i_analyze_start_pos3 = 0;
    int i_analyze_start_pos4 = 0;

    int i_ttc8_stmt_req_i_old = p_st_sess->i_ttc8_stmt_req_i;
    int i_ttc8_stmt_req_j_old = p_st_sess->i_ttc8_stmt_req_j;
    int i_ttc8_stmt_req_dml_old = p_st_sess->i_ttc8_stmt_req_dml;
    int i_ttc8_stmt_req_oci_after_dml_old = p_st_sess->i_ttc8_stmt_req_oci_after_dml;
    int i_CHR_conversion_flags_old = p_st_sess->i_CHR_conversion_flags;
    int i_useCLR_big_chunks_old = p_st_sess->i_useCLR_big_chunks;
    p_st_sess->i_ttc8_long_analyze_succ = FR_NO;

    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)                                       // seqNumber
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_options) != FR_SUCC)                       // options
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)                          // cursor
        goto error;
    // 使用新创建的statement请求进行判断
    if (i_cursor != 0)
    {
        ORA_PRINT_DBG("cursor:[%d], not 0\n", i_cursor);
        goto error;
    }
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_sql_flag) != FR_SUCC)                       // sqlStmt flag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_sql_len) != FR_SUCC)                      // sqlStmt.length
        goto error;
    // 需要存在sql语句的情况下进行判断
    if (c_sql_flag == APM_ORA_NULLPTR || i_sql_len <= 0)
        goto error;
    if (p_st_sess->i_send_typerep == FR_NO && p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_8)
    {
        if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == APM_ORA_FLAG_UNSET)
        {
            if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                goto error;
            if (uint64_tmp == 0x00000000)
                p_st_sess->i_oci_stmt_req_skip4_ttc8 = FR_YES;
            else
                p_st_sess->i_oci_stmt_req_skip4_ttc8 = FR_NO;
            ORA_PRINT_ALERT("set i_oci_stmt_req_skip4_ttc8 = %s\n", p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES ? "FR_YES" : "FR_NO");
        }
        if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
        {
            ORA_PRINT_DBG("skip 4 bytes after sqlStmt.length\n");
            if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                goto error;
        }
    }
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_al8i4_flag) != FR_SUCC)                     // al8i4.flag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_al8i4_len) != FR_SUCC)                    // al8i4.length
        goto error;
    // 目前的测试情况来看，从8.1.7.0到12.1.0.2，al8i4.flag为PTR，al8i4.length不大于0x0d
    if (c_al8i4_flag == APM_ORA_NULLPTR || i_al8i4_len > 0x0d)
        goto error;
    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after al8i4.length\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // NULLPTR or PTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // NULLPTR or PTR
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)                           // Long.MAX_VALUE
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)                           // rowsToFetch
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)                           // isPlsqlOrCall
        goto error;
    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after isPlsqlOrCall\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // bindFlag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)                          // numberOfBindPositions
        goto error;
    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after numberOfBindPositions\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // PTR or NULLPTR
        goto error;
    // TODO: 不支持p_st_sess->s_tns_version<312即8i的版本
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)                            // defColsFlag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)                          // defCols
        goto error;
    if (p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET)
    {
        i_analyze_start_pos1 = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
        if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // i
            goto error;
        if (ll_tmp == 0LL)
            p_st_sess->i_ttc8_stmt_req_i = FR_YES;
        else
        {
            p_st_sess->i_ttc8_stmt_req_i = FR_NO;
            p_st_sess->i_ttc8_stmt_req_j = FR_NO;
            p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
            p_st_sess->i_ttc8_stmt_req_oci_after_dml = FR_NO;
        }
        bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos1);
    }

    ORA_PRINT_FATAL("i_ttc8_stmt_req_i:[%d]\n", p_st_sess->i_ttc8_stmt_req_i);
    if (p_st_sess->i_ttc8_stmt_req_i == FR_YES)
    {
        if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // i
            goto error;
        if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
            goto error;
        if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
            goto error;

        if (p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET)
        {
            i_analyze_start_pos2 = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) == FR_SUCC && c_tmp == 0)
                p_st_sess->i_ttc8_stmt_req_j = FR_YES;
            else
            {
                p_st_sess->i_ttc8_stmt_req_j = FR_NO;
                p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
                p_st_sess->i_ttc8_stmt_req_oci_after_dml = FR_NO;
            }
            bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos2);
        }

        if (p_st_sess->i_ttc8_stmt_req_j == FR_YES)
        {
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
                goto error;
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // 0L
                goto error;
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
                goto error;
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // 0L
                goto error;
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // j
                goto error;
            if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
            {
                ORA_PRINT_DBG("skip 4 bytes after j\n");
                if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                    goto error;
            }

            if (p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET)
            {
                i_analyze_start_pos3 = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) == FR_SUCC && c_tmp == 0)
                    p_st_sess->i_ttc8_stmt_req_dml = FR_YES;
                else if (p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_8)
                {
                    bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos3);
                    if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 8, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                        goto error;
                    if (uint64_tmp == 0xfeffffffffffffff || uint64_tmp == 0xfffffffffffffffe)
                    {
                        if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr1) == FR_SUCC && // PTR or NULLPTR (isDML)
                            ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) == FR_SUCC && // currentRank
                            ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr2) == FR_SUCC && // PTR or NULLPTR (isDML)
                                c_ptr1 == APM_ORA_PTR && c_ptr2 == APM_ORA_PTR)
                            p_st_sess->i_ttc8_stmt_req_dml = FR_YES;
                        else
                        {
                            p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
                            p_st_sess->i_ttc8_stmt_req_oci_after_dml = FR_NO;
                        }
                    }
                    else
                    {
                        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                            goto error;
                        if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                            goto error;
                        if (uint64_tmp == 0x00000000)
                            p_st_sess->i_ttc8_stmt_req_dml = FR_YES;
                        else
                        {
                            p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
                            p_st_sess->i_ttc8_stmt_req_oci_after_dml = FR_NO;
                        }
                    }
                }
                else
                {
                    p_st_sess->i_ttc8_stmt_req_dml = FR_NO;
                    p_st_sess->i_ttc8_stmt_req_oci_after_dml = FR_NO;
                }
                bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos3);
            }

            if (p_st_sess->i_ttc8_stmt_req_dml == FR_YES)
            {
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr1) != FR_SUCC) // PTR or NULLPTR (isDML)
                    goto error;
                if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // currentRank
                    goto error;
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_ptr2) != FR_SUCC) // PTR or NULLPTR (isDML)
                    goto error;

                if (p_st_sess->i_ttc8_stmt_req_oci_after_dml == APM_ORA_FLAG_UNSET)
                {
                    i_analyze_start_pos4 = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
                    if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                        goto error;
                    if (uint64_tmp == 0x00000000)
                        p_st_sess->i_ttc8_stmt_req_oci_after_dml = FR_YES;
                    else
                        p_st_sess->i_ttc8_stmt_req_oci_after_dml = FR_NO;
                    bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos4);
                }

                if (p_st_sess->i_ttc8_stmt_req_oci_after_dml == FR_YES)
                {
                    if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                        goto error;
                }
            }
        }
    }

    if (p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
    {
        if (bytebuff_remaining(p_st_ora_packet->p_st_packet) < 10)
            goto error;
        if (bytebuff_peek_bytes(p_st_ora_packet->p_st_packet, arr_sql_head, 10) != FR_SUCC)
            goto error;
        if (ora_is_sql(arr_sql_head, 10) == FR_SUCC)
            p_st_sess->i_CHR_conversion_flags = FR_NO;
        else
            p_st_sess->i_CHR_conversion_flags = FR_YES;
    }

    if (ora_mar_unmarshalCHR(i_sql_len, p_st_sess, p_st_ora_packet, &p_tmp, &i_tmp) == FR_SUCC) // sqlStmt
    {
        if (ora_is_sql(p_tmp, i_tmp) != FR_SUCC)
        {
            ora_free((void **) &p_tmp);
            goto error;
        }
        if (ora_is_sql_select(p_tmp, i_tmp) != FR_SUCC)
        {
            ora_free((void **) &p_tmp);
            ORA_PRINT_DBG("is not select sql\n");
            i_CHR_conversion_flags_old = p_st_sess->i_CHR_conversion_flags;
            i_useCLR_big_chunks_old = p_st_sess->i_useCLR_big_chunks;
            goto error;
        }
        ora_free((void **) &p_tmp);
    }
    else
        goto error;

    if (ora_mar_unmarshalUB4Array(i_al8i4_len, p_st_sess, p_st_ora_packet) != FR_SUCC) // al8i4
        goto error;


    ORA_PRINT_ALERT("set i_ttc8_stmt_req_i = %s, i_ttc8_stmt_req_j = %s, i_ttc8_stmt_req_dml = %s, i_ttc8_stmt_req_oci_after_dml = %s, i_CHR_conversion_flags = %s\n",
                  p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_req_i == FR_YES ? "FR_YES" : "FR_NO"),
                  p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_req_j == FR_YES ? "FR_YES" : "FR_NO"),
                  p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_req_dml == FR_YES ? "FR_YES" : "FR_NO"),
                  p_st_sess->i_ttc8_stmt_req_oci_after_dml == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_req_oci_after_dml == FR_YES ? "FR_YES" : "FR_NO"),
                  p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_CHR_conversion_flags == FR_YES ? "FR_YES" : "FR_NO"));

    return FR_SUCC;
error:
    p_st_ora_packet->fragment_state = APM_ORA_FRAGMENT_INIT;
    p_st_sess->i_ttc8_stmt_req_i = i_ttc8_stmt_req_i_old;
    p_st_sess->i_ttc8_stmt_req_j = i_ttc8_stmt_req_j_old;
    p_st_sess->i_ttc8_stmt_req_dml = i_ttc8_stmt_req_dml_old;
    p_st_sess->i_ttc8_stmt_req_oci_after_dml = i_ttc8_stmt_req_oci_after_dml_old;
    p_st_sess->i_CHR_conversion_flags = i_CHR_conversion_flags_old;
    p_st_sess->i_useCLR_big_chunks = i_useCLR_big_chunks_old;
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  解析0x035E的sql请求包
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_hash_report                    (数据上报)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ora_ttc8_oall8_unpack_req_oci(Conntrack *p_st_conn
                                            , L7session_ora *p_st_sess
                                            , L7_ora_packet *p_st_ora_packet
                                            , Frhash_header *p_st_hash_report)
{
    ORA_PRINT_INFO("enter __ora_ttc8_oall8_unpack_req_oci\n");
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    Sql_statement *p_st_stmt = NULL;
    Sql_resultset *p_st_rs = NULL;

    char c_tmp = 0;
    short s_tmp = 0;
    int i_tmp = 0;
    long long ll_tmp = 0LL;
    char *p_tmp = NULL;

    long long ll_options = 0LL;
    unsigned long ul_curr_cursor = 0L;
    int i_sql_len = 0;
    int i_al8i4_len = 0;
    long long ll_isPlsqlOrCall = 0LL;
    char *p_sql = NULL;
    unsigned int ui_sql_utf8_len = 0;
    int i_loop = 0;
    int i_defCols_len = 0;
    int i_numberOfBindPositions_len = 0;
    int i_report_stmt_req = FR_NO;
    int i_sql_exists = FR_NO;
    int i_reported_last_resp = FR_NO;
    int i_set_sql = FR_NO;
    int i_set_metadata_bind = FR_NO;
    int i_set_metadata_define = FR_NO;
    int i_set_bind_value = FR_NO;
    uint64_t uint64_tmp = 0LL;

    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC) // seqNumber
        goto error;

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_options) != FR_SUCC) // options
        goto error;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // cursor
        goto error;

    /**
    * 发送sql请求时的cursor，如果为0，表示当前是一个新的statement，客户端会使用服务端返回的另外一个cursor执行同一个statement请求
    * 所以cursor为0时，需要新建一个 Ora_statement，
    */
    ul_curr_cursor = (unsigned long) i_tmp;
    if (ul_curr_cursor == 0L)
    {
        // 新建一个游标为0的 Sql_statement
        if (ora_set_new_stmt(p_st_conn, &p_st_stmt) != FR_SUCC)
            goto error;
        ORA_PRINT_DBG("create new stmt of cursor:[0]\n");
    }
    else
    {
        // 从当前的列表中根据 cursor 获取 Ora_statement
        if ((p_st_stmt = ora_get_stmt(p_st_conn, ul_curr_cursor)) == NULL)
        {
            if (ora_set_new_stmt(p_st_conn, &p_st_stmt) != FR_SUCC)
                goto error;
            p_st_stmt->l_cursor_id = ul_curr_cursor;
            ORA_PRINT_DBG("create new stmt of cursor:[%ld]\n", p_st_stmt->l_cursor_id);
        }
    }
    p_st_curr_sess->ul_cursor = ul_curr_cursor;

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // sqlStmt flag
        goto error;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_sql_len) != FR_SUCC) // sqlStmt.length
        goto error;
    ORA_PRINT_DBG("i_sql_len:[%d]\n", i_sql_len);

    if (p_st_sess->i_send_typerep == FR_NO && p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_8)
    {
        if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == APM_ORA_FLAG_UNSET)
        {
            if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                goto error;
            if (uint64_tmp == 0)
                p_st_sess->i_oci_stmt_req_skip4_ttc8 = FR_YES;
            else
                p_st_sess->i_oci_stmt_req_skip4_ttc8 = FR_NO;
            ORA_PRINT_ALERT("set i_oci_stmt_req_skip4_ttc8 = %s\n", p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES ? "FR_YES" : "FR_NO");
        }
        if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
        {
            ORA_PRINT_DBG("skip 4 bytes after sqlStmt.length\n");
            if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                goto error;
        }
    }

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // al8i4 flag
        goto error;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_al8i4_len) != FR_SUCC) // al8i4.length
        goto error;

    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after al8i4.length\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // NULLPTR or PTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // NULLPTR or PTR
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // Long.MAX_VALUE
        goto error;
    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // rowsToFetch
        goto error;

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_isPlsqlOrCall) != FR_SUCC) // isPlsqlOrCall
        goto error;

    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after isPlsqlOrCall\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // bindFlag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_numberOfBindPositions_len) != FR_SUCC) // numberOfBindPositions
        goto error;

    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after numberOfBindPositions\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
        goto error;
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
        goto error;

    // TODO: 不支持p_st_sess->s_tns_version<312即8i的版本
    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // defColsFlag
        goto error;
    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_defCols_len) != FR_SUCC) // defCols
        goto error;
    ORA_PRINT_INFO("unmarshal defColsFlag defCols\n");

    if (p_st_sess->i_ttc8_stmt_req_i == FR_YES)
    {
        if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // i
            goto error;
        if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
            goto error;
        if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
            goto error;
        ORA_PRINT_INFO("unmarshal i PTR PTR\n");

        if (p_st_sess->i_ttc8_stmt_req_j == FR_YES)
        {
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
                goto error;
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // 0L
                goto error;
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR
                goto error;
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // 0L
                goto error;
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // j
                goto error;
            ORA_PRINT_INFO("unmarshal PTR 0L PTR 0L j\n");

            if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
            {
                ORA_PRINT_DBG("skip 4 bytes after j\n");
                if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                    goto error;
            }

            if (p_st_sess->i_ttc8_stmt_req_dml == FR_YES)
            {
                ORA_PRINT_WARN("s_tns_version >= 315\n");
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR (isDML)
                    goto error;
                if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // currentRank
                    goto error;
                if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR or NULLPTR (isDML)
                    goto error;

                if (p_st_sess->i_ttc8_stmt_req_oci_after_dml == FR_YES)
                {
                    ORA_PRINT_DBG("skip 4 bytes after isDML\n");
                    if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                        goto error;
                }
            }
        }
    }

    if (p_st_stmt->p_sql != NULL)
        i_sql_exists = FR_YES;

    if (i_sql_len > 0)
    {
        if (ora_mar_unmarshalCHR(i_sql_len, p_st_sess, p_st_ora_packet, &p_tmp, &i_tmp) == FR_SUCC) // sqlStmt
        {
            if (p_tmp != NULL)
            {
                if (ora_is_sql_dml(p_tmp, i_tmp) == FR_SUCC)
                    p_st_stmt->i_is_dml = FR_YES;
                else
                    p_st_stmt->i_is_dml = FR_NO;

                if (ora_str_to_utf8(p_st_sess, p_st_sess->s_cli_charset_out, p_tmp, (unsigned int) i_tmp, &p_sql, &ui_sql_utf8_len) != FR_SUCC)
                    goto error;
                // 如果stmt中已存在sql的话，则先上报之前的信息
                if (i_sql_exists == FR_YES)
                {
                    if (ora_report_stmt_resp(p_st_conn, p_st_sess, p_st_stmt, p_st_hash_report, FR_YES) != FR_SUCC)
                        goto error;
                    i_reported_last_resp = FR_YES;
                }

                ORA_PRINT_WARN("sql before delete comments:[%s]\n", p_sql);
                ora_sql_delete_comments(&p_sql);
                frdb_reset_sql(p_st_stmt, p_sql);
                i_set_sql = FR_YES;
                i_report_stmt_req = FR_YES;
                ORA_PRINT_ERR("sql after delete comments:[%s]\n", p_sql);
                p_sql = NULL;
            }
            ora_free((void **) &p_tmp);
        }
        else
            goto error;
    }

    if (ora_mar_unmarshalUB4Array(i_al8i4_len, p_st_sess, p_st_ora_packet) != FR_SUCC) // al8i4
        goto error;

    p_st_stmt->ll_ora_options = ll_options;
    ORA_PRINT_DBG("ll_options:[%lld], i_numberOfBindPositions_len:[%d], i_defCols_len:[%d]\n", ll_options, i_numberOfBindPositions_len, i_defCols_len);
    if (i_numberOfBindPositions_len > 0)
    {
        ORA_PRINT_INFO("unmarshal bind dty\n");
        frlist_remove_all(&(p_st_stmt->st_metadata_bind), frdb_metadata_node_free);
        for (i_loop = 0; i_loop < i_numberOfBindPositions_len; i_loop++)
        {
            if (ora_ttc8_tti_oac_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet, APM_ORA_OACTYPE_BIND, p_st_stmt) != FR_SUCC)
                goto error;
            i_set_metadata_bind = FR_YES;
        }
    }

    // 不支持c_ttc_version<2的版本
    if (i_defCols_len > 0)
    {
        ORA_PRINT_INFO("unmarshal definition dty\n");
        frlist_remove_all(&(p_st_stmt->st_metadata_define), frdb_metadata_node_free);
        for (i_loop = 0; i_loop < i_defCols_len; i_loop++)
        {
            if (ora_ttc8_tti_oac_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet, APM_ORA_OACTYPE_DEFINE, p_st_stmt) != FR_SUCC)
                goto error;
            i_set_metadata_define = FR_YES;
        }
    }

    if ((ll_options & 0x20) != 0LL && i_numberOfBindPositions_len > 0)
    {
        // 解析bind值
        ORA_PRINT_INFO("unmarshal bind value\n");
        if (i_sql_exists == FR_YES && i_reported_last_resp == FR_NO)
        {
            if (ora_report_stmt_resp(p_st_conn, p_st_sess, p_st_stmt, p_st_hash_report, FR_YES) != FR_SUCC)
                goto error;
            i_reported_last_resp = FR_YES;
        }
        if ((p_st_rs = frdb_get_last_resultset(p_st_stmt)) == NULL)
            goto error;
        frlist_remove_all(&(p_st_rs->st_bind_list), frdb_field_bind_node_free);
        short s_ttc_code;
        while(bytebuff_remaining(p_st_ora_packet->p_st_packet) > 0)
        {
            ORA_PRINT_INFO("unmarshal bind value next\n");
            i_report_stmt_req = FR_YES;
            if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_ttc_code) != FR_SUCC)
                goto error;
            if (s_ttc_code != APM_TTC_CODE_TTIRXD)
                goto error;
            if (ora_ttc8_oall8_bind_unpack(p_st_conn, p_st_sess, p_st_ora_packet, p_st_stmt, p_st_hash_report) != FR_SUCC)
                goto error;
            i_set_bind_value = FR_YES;
        }
    }

    // 设置l4层信息
    if (frdb_set_resultset_req(p_st_stmt, FRDB_LAST, 0, bytebuff_length(p_st_ora_packet->p_st_packet), &(p_st_ora_packet->st_timestamp_first), &(p_st_ora_packet->st_timestamp_last)) != FR_SUCC)
        goto error;

    // 数据上报
    if (i_report_stmt_req == FR_YES && ora_report_stmt_req(p_st_conn, p_st_sess, p_st_stmt, p_st_hash_report) != FR_SUCC)
        goto error;

    return FR_SUCC;
error:
    ora_free((void **) &p_tmp);
    if (ora_packet_is_in_fragment(p_st_ora_packet) && ul_curr_cursor != 0L)
    {
        if (i_set_sql)
            ora_free((void **) &(p_st_stmt->p_sql));
        if (i_set_metadata_bind)
            frlist_remove_all(&(p_st_stmt->st_metadata_bind), frdb_metadata_node_free);
        if (i_set_metadata_define)
            frlist_remove_all(&(p_st_stmt->st_metadata_define), frdb_metadata_node_free);
        if (i_set_bind_value)
            frlist_remove_all(&(p_st_rs->st_bind_list), frdb_field_bind_node_free);
    }
    else
    {
        if (ul_curr_cursor == 0L)
            frdb_statement_free(&(p_st_session_private->p_st_req->p_st_stmt));
        ora_free((void **) &p_sql);
    }
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  解析0x035E的sql请求包
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_hash_report                    (数据上报)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_unpack_req(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet
                            , Frhash_header *p_st_hash_report)
{
    if (p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET)
        return FR_FAIL;

    if (p_st_sess->i_use_special_field == FR_YES)
    {
        // 参数未确定时，先分析长连接参数
        if (p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET ||
            p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET ||
            p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET ||
            p_st_sess->i_ttc8_stmt_req_oci_after_dml == APM_ORA_FLAG_UNSET ||
            p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
        {
            int i_analyze_start_pos = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
            if (__ora_ttc8_oall8_analyze_req_oci(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                return FR_FAIL;
            bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos);
        }
        return __ora_ttc8_oall8_unpack_req_oci(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report);
    }
    else
    {
        // 参数未确定时，先分析长连接参数
        if (p_st_sess->i_ttc8_stmt_req_i == APM_ORA_FLAG_UNSET ||
                p_st_sess->i_ttc8_stmt_req_j == APM_ORA_FLAG_UNSET ||
                p_st_sess->i_ttc8_stmt_req_dml == APM_ORA_FLAG_UNSET ||
                p_st_sess->i_CHR_conversion_flags == APM_ORA_FLAG_UNSET)
        {
            int i_analyze_start_pos = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
            if (__ora_ttc8_oall8_analyze_req_jdbc(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                return FR_FAIL;
            bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_analyze_start_pos);
        }
        return __ora_ttc8_oall8_unpack_req_jdbc(p_st_conn, p_st_sess, p_st_ora_packet, p_st_hash_report);
    }
}



/*******************************************************************************
*  FUNC     :  解析0x0303的sql请求包
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_hash_report                    (数据上报)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_unpack0303_req(Conntrack *p_st_conn
                                , L7session_ora *p_st_sess
                                , L7_ora_packet *p_st_ora_packet
                                , Frhash_header *p_st_hash_report)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    Sql_statement *p_st_stmt = NULL;

    char c_tmp = 0;
    short s_tmp = 0;
    int i_tmp = 0;
    char *p_tmp = NULL;
    uint64_t uint64_tmp = 0LL;

    unsigned long ul_curr_cursor = 0L;
    int i_sql_len = 0;
    char *p_sql = NULL;
    unsigned int ui_sql_utf8_len = 0;
    int i_report_stmt_req = FR_NO;
    int i_set_sql = FR_NO;

    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC) // seqNumber
        goto error;

    if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // cursor
        goto error;

    ul_curr_cursor = (unsigned long) i_tmp;
    // 从当前的列表中直接根据 cursor 获取 Ora_statement，没有则出错
    if ((p_st_stmt = ora_get_stmt(p_st_conn, ul_curr_cursor)) == NULL)
    {
        if (ul_curr_cursor == 0L)
        {
            ORA_PRINT_EMERG("fatal to get stmt of cursor:[%lu]\n", ul_curr_cursor);
            goto error;
        }
        ORA_PRINT_WARN("unexpected fail to get stmt of cursor:[%lu]\n", ul_curr_cursor);
        if ((p_st_stmt = ora_get_new_stmt(p_st_conn)) == NULL)
        {
            // 新建一个游标为0的 Sql_statement
            if (ora_set_new_stmt(p_st_conn, &p_st_stmt) != FR_SUCC)
                goto error;
        }
        // 将游标0更新为从服务端返回来的游标值
        if (frdb_add_statement(p_st_session_private->p_hash_stmt, ul_curr_cursor, p_st_stmt) != FR_SUCC)
            goto error;
        ORA_PRINT_DBG("add stmt of cursor 0 to hash_stmt and update to cursor:[%lu]\n", ul_curr_cursor);
        p_st_session_private->p_st_req->p_st_stmt = NULL;
    }
    p_st_curr_sess->ul_cursor = ul_curr_cursor;

    ORA_PRINT_FATAL("i_oci_stmt_req_skip4_ttc7:[%d]\n", p_st_sess->i_oci_stmt_req_skip4_ttc7);

    if (p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_8 && p_st_sess->i_oci_stmt_req_skip4_ttc7 == APM_ORA_FLAG_UNSET)
    {
        int i_pos = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
        if (bytebuff_get_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
            goto error;
        if (uint64_tmp == 0x00000000 &&
                ((ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) == FR_SUCC &&
                c_tmp == APM_ORA_PTR &&
                ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &i_tmp) == FR_SUCC &&
                i_tmp > 0) ||
                (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) == FR_SUCC &&
                 c_tmp == APM_ORA_NULLPTR &&
                 ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &i_tmp) == FR_SUCC &&
                 i_tmp == 0)))
            p_st_sess->i_oci_stmt_req_skip4_ttc7 = FR_YES;
        else
            p_st_sess->i_oci_stmt_req_skip4_ttc7 = FR_NO;
        if (bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_pos) != FR_SUCC)
            goto error;
    }

    if (p_st_sess->i_oci_stmt_req_skip4_ttc7 == FR_YES)
    {
        ORA_PRINT_NOTICE("oci skip 4 bytes after cursor\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // sqlStmt flag
        goto error;

    if (ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &i_sql_len) != FR_SUCC) // sqlStmt.length
        goto error;

    if (p_st_sess->i_oci_stmt_req_skip4_ttc7 == FR_YES)
    {
        ORA_PRINT_NOTICE("oci skip 4 bytes after sqlStmt.length\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (i_sql_len > 0)
    {
        ORA_PRINT_DBG("i_sql_len:[%d]\n", i_sql_len);
        if (ora_mar_unmarshalCHR(i_sql_len, p_st_sess, p_st_ora_packet, &p_tmp, &i_tmp) == FR_SUCC) // sqlStmt
        {
            if (p_tmp)
            {
                if (ora_str_to_utf8(p_st_sess, p_st_sess->s_cli_charset_out, p_tmp, (unsigned int) i_tmp, &p_sql, &ui_sql_utf8_len) != FR_SUCC)
                    goto error;

                // 如果stmt中已存在sql的话，则先上报之前的信息
                if (p_st_stmt->p_sql != NULL && ora_report_stmt_resp(p_st_conn, p_st_sess, p_st_stmt, p_st_hash_report, FR_YES) != FR_SUCC)
                    goto error;

                ORA_PRINT_WARN("sql before delete comments:[%s]\n", p_sql);
                ora_sql_delete_comments(&p_sql);
                frdb_reset_sql(p_st_stmt, p_sql);
                i_set_sql = FR_YES;
                i_report_stmt_req = FR_YES;
                ORA_PRINT_ERR("sql after delete comments:[%s]\n", p_sql);
                p_sql = NULL;
            }
            ora_free((void **) &p_tmp);
        }
        else
            goto error;
    }

    // 设置l4层信息
    if (frdb_set_resultset_req(p_st_stmt, FRDB_LAST, 0, bytebuff_length(p_st_ora_packet->p_st_packet), &(p_st_ora_packet->st_timestamp_first), &(p_st_ora_packet->st_timestamp_last)) != FR_SUCC)
        goto error;

    // 数据上报
    if (i_report_stmt_req == FR_YES && ora_report_stmt_req(p_st_conn, p_st_sess, p_st_stmt, p_st_hash_report) != FR_SUCC)
        goto error;

    return FR_SUCC;
error:
    ora_free((void **) &p_tmp);
    if (ora_packet_is_in_fragment(p_st_ora_packet) && ul_curr_cursor != 0L)
    {
        if (i_set_sql)
            ora_free((void **) &(p_st_stmt->p_sql));
    }
    else
    {
        if (ul_curr_cursor == 0L)
            frdb_statement_free(&(p_st_session_private->p_st_req->p_st_stmt));
        ora_free((void **) &p_sql);
    }
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  RPC -> readBVC
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_read_BVC(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    Sql_statement *p_st_stmt = NULL;

    int i_tmp = 0;
    int i_byte_num = 0;

    if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) == FR_FAIL)
        goto error;

    if ((p_st_stmt = ora_get_current_stmt(p_st_conn)) == NULL)
        goto error;

    i_byte_num = frdb_get_column_nums(p_st_stmt) / 8 + (frdb_get_column_nums(p_st_stmt) % 8 != 0 ? 1 : 0);
    if (i_byte_num > 0 && ora_ttc8_tti_rxd_unmarshalBVC(p_st_conn, p_st_sess, p_st_ora_packet, i_byte_num) != FR_SUCC)
        goto error;

    // 记录当前解析完的位置点
    p_st_ora_packet->i_analyze_position = bytebuff_getPosition(p_st_ora_packet->p_st_packet);

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  RPC -> readIOV
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_read_IOV(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    Sql_statement *p_st_stmt = NULL;
    Sql_metadata_info *p_st_metadata = NULL;
    Frlist_node *p_st_node = NULL;
    short s_tmp = 0;

    if (ora_ttc8_tti_iov_unmarshalV10(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
        goto error;

    if ((p_st_stmt = ora_get_current_stmt(p_st_conn)) == NULL)
        goto error;

    p_st_node = FRLIST_FIRST_NODE(&(p_st_stmt->st_metadata_bind));
    while (p_st_node)
    {
        p_st_metadata = (Sql_metadata_info *) FRLIST_GET_NODE_DATA(p_st_node);

        if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC) // bindtype
            goto error;
        if (s_tmp == 0)
        {
            ORA_PRINT_EMERG("bindtype == 0\n");
            ORA_FRLOG_ERROR("bindtype == 0");
            goto error;
        }
        else if ((s_tmp & 0x10) == 0)
        {
            ORA_PRINT_DBG("bindtype = %02x, i_isuseless = 1\n", s_tmp);
            p_st_metadata->i_isuseless = FR_YES;
        }

        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }

    // 记录当前解析完的位置点
    p_st_ora_packet->i_analyze_position = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
    p_st_ora_packet->i_iov_processed_flag = FR_YES;

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  RPC -> readRXD
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_read_RXD(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    Sql_statement *p_st_stmt = NULL;
    Sql_metadata_info *p_st_metadata = NULL;
    Frlist_node *p_st_node = NULL;

    char c_tmp = 0;
    short s_tmp = 0;
    short s_k = 0;
    int i_loop = 0;
#if APM_ORA_DBG
    int i_pos_start = 0;
#endif

    // FIXME: 这里应该使用更好的算法来对应
    if (p_st_sess->i_use_special_field == FR_YES)
    {
        if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_k) != FR_SUCC) // k
            goto error;
        if (s_k == 0x00)
        {
            if (bytebuffer_backspace(p_st_ora_packet->p_st_packet, 1) != FR_SUCC)
                goto error;
        }
        else
        {
            if (ora_mar_peekUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
                goto error;
            if (s_tmp == 0x2c)
            {
                ORA_PRINT_WARN("use 0x2c to detect row in one\n");
                if (ora_mar_skip(p_st_ora_packet, (unsigned long long) s_k) != FR_SUCC)
                    goto error;
                goto success;
            }
            if (bytebuffer_backspace(p_st_ora_packet->p_st_packet, 1) != FR_SUCC)
                goto error;
        }
    }

    if ((p_st_stmt = ora_get_current_stmt(p_st_conn)) == NULL)
        goto error;

    if (frlist_size(&(p_st_stmt->st_metadata_define)) > 0 && frlist_size(&(p_st_stmt->st_metadata_column)) == 0)
    {
        ORA_PRINT_DBG("get metadata from define list, size:[%d]\n", frlist_size(&(p_st_stmt->st_metadata_define)));
        p_st_node = FRLIST_FIRST_NODE(&(p_st_stmt->st_metadata_define));
    }
    else if (frlist_size(&(p_st_stmt->st_metadata_column)) > 0)
    {
        ORA_PRINT_DBG("get metadata from column list, size:[%d]\n", frlist_size(&(p_st_stmt->st_metadata_column)));
        p_st_node = FRLIST_FIRST_NODE(&(p_st_stmt->st_metadata_column));
    }
    else if (frlist_size(&(p_st_stmt->st_metadata_bind)) > 0)
    {
        ORA_PRINT_DBG("get metadata from bind list, size:[%d]\n", frlist_size(&(p_st_stmt->st_metadata_bind)));
        p_st_node = FRLIST_FIRST_NODE(&(p_st_stmt->st_metadata_bind));
    }
    else
    {
        ORA_PRINT_EMERG("Doesn't exists metadata\n");
        goto error;
    }

    /*
    if (p_st_stmt->i_is_dml_returning == FR_YES && frlist_size(&(p_st_stmt->st_metadata_column)) > 0)
    {
        ORA_PRINT_DBG("get metadata from column list, size:[%d] | define list size:[%d]\n", frlist_size(&(p_st_stmt->st_metadata_column)), frlist_size(&(p_st_stmt->st_metadata_define)));
        p_st_node = FRLIST_FIRST_NODE(&(p_st_stmt->st_metadata_column));
    }
    else if (frlist_size(&(p_st_stmt->st_metadata_bind)) > 0 && frlist_size(&(p_st_stmt->st_metadata_define)) == 0)
    {
        ORA_PRINT_DBG("get metadata from bind list, size:[%d]\n", frlist_size(&(p_st_stmt->st_metadata_bind)));
        p_st_node = FRLIST_FIRST_NODE(&(p_st_stmt->st_metadata_bind));
    }
    else if (frlist_size(&(p_st_stmt->st_metadata_define)) > 0)
    {
        ORA_PRINT_DBG("get metadata from define list, size:[%d]\n", frlist_size(&(p_st_stmt->st_metadata_define)));
        p_st_node = FRLIST_FIRST_NODE(&(p_st_stmt->st_metadata_define));
    }
    else
    {
        ORA_PRINT_EMERG("Doesn't exists metadata\n");
        ORA_FRLOG_ERROR("Doesn't exists metadata");
        goto error;
    }
    */

    while (p_st_node)
    {
        p_st_metadata = (Sql_metadata_info *) FRLIST_GET_NODE_DATA(p_st_node);
//        ORA_PRINT_DBG("while list metadata i_bvc_found:[%d] BITTEST(p_st_curr_sess->arr_columns_bit, i_loop):[%d]\n", p_st_curr_sess->i_bvc_found, BITTEST(p_st_curr_sess->arr_columns_bit, i_loop));
        if (!p_st_curr_sess->i_bvc_found || BITTEST(p_st_curr_sess->arr_columns_bit, i_loop))
        {
//            ORA_PRINT_CRIT("p_st_metadata => i_data_type:[%d], i_isuseless:[%d], i_isnullbydescribe:[%d] i_oacflg:[%d]\n",
//                    p_st_metadata->i_data_type,
//                    p_st_metadata->i_isuseless,
//                    p_st_metadata->i_isnullbydescribe,
//                    p_st_metadata->s_ora_oacflg);

#if APM_ORA_DBG
            i_pos_start = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
#endif

            ORA_PRINT_DTY_INFO((char *) "%s start\n", p_st_metadata->i_data_type);
            switch (p_st_metadata->i_data_type)
            {
                case ORA_DTY_VARCHAR:      // 1 0x01
                    if (ora_varchar_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_NUMBER:       // 2 0x02
                    if (ora_number_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_VARNUM:       // 6 0x06
                    if (ora_varnum_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_LONG:         // 8 0x08
                    if (ora_long_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_DATE:         // 12 0x0c
                    if (ora_date_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_RAW:          // 23 0x17
                    if (ora_raw_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_LONG_RAW:     // 24 0x18
                    if (ora_longraw_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_CHAR:         // 96 0x60
                    if (ora_char_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_BINARY_FLOAT: // 100 0x64
                    if (ora_binaryfloat_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_BINARY_DOUBLE: // 101 0x65
                    if (ora_binarydouble_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_RESULT_SET:   // 102 0x66
                    if (ora_resultset_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_ROWID2:       // 11 0x0b
                case ORA_DTY_ROWID:        // 104 0x68
                case ORA_DTY_UROWID:       // 208 0xd0
                    if (ora_rowid_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_ANYTYPE:   // 58 0x3a
                case ORA_DTY_NAMED_TYPE:   // 109 0x6d
                case ORA_DTY_NAMED_TYPE2:  // 121 0x79
                    if (ora_namedtype_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_REF_TYPE:     // 111 0x6f
                    if (ora_reftype_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_CLOB:         // 112 0x70
                    if (ora_clob_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_stmt->ll_ora_options, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_BLOB:         // 113 0x71
                    if (ora_blob_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_BFILE:        // 114 0x72
                    ORA_PRINT_ALERT("BFILE ll_options:[%lld]\n", p_st_stmt->ll_ora_options);
                    if (ora_bfile_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_stmt->ll_ora_options, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_TIMESTAMP:    // 180 0xb4
                    if (ora_timestamp_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_TIMESTAMPTZ:  // 181 0xb5
                    if (ora_timestamptz_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_INTERVALYM:   // 182 0xb6
                    if (ora_intervalym_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_INTERVALDS:   // 183 0xb7
                    if (ora_intervalds_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                case ORA_DTY_TIMESTAMPLTZ: // 231 0xe7
                    if (ora_timestampltz_accessor_unmarshal_one_row(p_st_conn, p_st_sess, p_st_ora_packet, p_st_metadata) != FR_SUCC)
                        goto error;
                    break;

                default:
                    ORA_PRINT_EMERG("Don't know dataType:[%d]\n", p_st_metadata->i_data_type);
                    break;
            }
            ORA_PRINT_DTY_INFO((char *) "%s done\n", p_st_metadata->i_data_type);
#if APM_ORA_DBG
            ORA_PRINT_PACKET_SPECIFIED("unmarshaled one row", p_st_ora_packet, i_pos_start, bytebuff_getPosition(p_st_ora_packet->p_st_packet) - i_pos_start);
#endif

            if (p_st_metadata->i_data_type != ORA_DTY_NAMED_TYPE &&
                    p_st_metadata->i_data_type != ORA_DTY_NAMED_TYPE2 && p_st_metadata->i_isuseless != FR_YES)
            {
                if (p_st_sess->i_use_special_field == FR_NO) // jdbc
                {
                    if (p_st_curr_sess->i_iov_processed_flag) // 0x0b开头的响应
                    {
                        // TODO: 1 or 2
//                        if (ora_mar_skip(p_st_ora_packet, 1) != FR_SUCC)
//                            goto error;
                        if (ora_mar_unmarshalSB1(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)
                            goto error;
                    }
                }
                else // oci
                {
                    if (p_st_curr_sess->i_iov_processed_flag) // 0x0b开头的响应
                    {
                        if (p_st_metadata->s_ora_oacflg != 0x00 && p_st_metadata->s_ora_oacflg != 0x43)
                        {
                            if (ora_mar_skip(p_st_ora_packet, 2) != FR_SUCC)
                                goto error;
                        }
                    }
                    // TODO: 不考虑8i的版本
//                    else if (p_st_sess->s_tns_version <= 310)
//                    {
//                        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
//                            goto error;
//                    }
                }
            }
        }
        i_loop++;
        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }

    p_st_curr_sess->i_bvc_found = FR_NO;

    // 记录当前解析完的位置点
    p_st_ora_packet->i_analyze_position = bytebuff_getPosition(p_st_ora_packet->p_st_packet);

success:
    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  RPC -> readRPA，服务端返回一个申请到的游标
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_read_RPA(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    Sql_statement *p_st_stmt = NULL;
    char *p_tmp = NULL;
    long long ll_tmp = 0LL;
    int i_arr_len = 0;
    int i_loop = 0;
    int *p_arr_int = NULL;
    int i_m = 0;
    int i_n = 0;
    int i_g = 0;
    int i_p = 0;
    unsigned long ul_curr_cursor = 0L;
    short s_tmp = 0;
    uint64_t uint64_tmp = 0LL;
    int i_ttc8_stmt_resp_rpag_old = p_st_sess->i_ttc8_stmt_resp_rpag;
    int i_ttc8_stmt_resp_rpadml_old = p_st_sess->i_ttc8_stmt_resp_rpadml;

    p_st_curr_sess->ui_batch_count = 0;
    ora_free((void **) &(p_st_curr_sess->p_ll_rows));

    if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_arr_len) != FR_SUCC) // i
        goto error;
    if (i_arr_len <= 2)
        goto error;
    if ((p_arr_int = (int *) ora_malloc(i_arr_len * sizeof(int), bytebuff_remaining(p_st_ora_packet->p_st_packet))) == NULL)
    {
        ORA_MALLOCK_ERR;
        goto error;
    }
    for (i_loop = 0; i_loop < i_arr_len; i_loop++)
    {
        if (ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &(p_arr_int[i_loop])) != FR_SUCC) // arrayOfInt
            goto error;
    }

    ul_curr_cursor = (unsigned long) p_arr_int[2];
    p_st_curr_sess->i_cursor_inrpa = p_arr_int[2];
    ora_free((void **) &p_arr_int);

    if (ul_curr_cursor == 0L)
    {
        ul_curr_cursor = p_st_session_private->p_st_curr_sess->ul_cursor;
        if (p_st_session_private->p_st_curr_sess->ul_cursor == 0L)
        {
            if ((p_st_stmt = ora_get_new_stmt(p_st_conn)) == NULL)
            {
                ORA_PRINT_EMERG("Can not get stmt of cursor:[%lu]\n", ul_curr_cursor);
                ORA_FRLOG_ERROR("Can not get stmt of cursor:[%lu]", ul_curr_cursor);
                goto error;
            }
        }
        else
        {
            if ((p_st_stmt = ora_get_stmt(p_st_conn, ul_curr_cursor)) == NULL)
            {
                ORA_PRINT_EMERG("Can not get stmt of cursor:[%lu]\n", ul_curr_cursor);
                ORA_FRLOG_ERROR("Can not get stmt of cursor:[%lu]", ul_curr_cursor);
                goto error;
            }
        }
    }
    else
    {
        if (p_st_session_private->p_st_curr_sess->ul_cursor == 0L)
        {
            p_st_session_private->p_st_curr_sess->ul_cursor = ul_curr_cursor;
            if ((p_st_stmt = ora_get_new_stmt(p_st_conn)) == NULL)
            {
                ORA_PRINT_EMERG("Can not get stmt of cursor:[%lu]\n", ul_curr_cursor);
                ORA_FRLOG_ERROR("Can not get stmt of cursor:[%lu]", ul_curr_cursor);
                goto error;
            }

            // 将游标0更新为从服务端申请回来的游标值
            if (frdb_add_statement(p_st_session_private->p_hash_stmt, ul_curr_cursor, p_st_stmt) != FR_SUCC)
                goto error;
            p_st_session_private->p_st_req->p_st_stmt = NULL;
            ORA_PRINT_DBG("add stmt of cursor 0 to hash_stmt and update to cursor:[%lu]\n", ul_curr_cursor);

        }
        else
        {
            p_st_session_private->p_st_curr_sess->ul_cursor = ul_curr_cursor;
            if ((p_st_stmt = ora_get_stmt(p_st_conn, ul_curr_cursor)) == NULL)
            {
                ORA_PRINT_EMERG("Can not get stmt of cursor:[%lu]\n", ul_curr_cursor);
                ORA_FRLOG_ERROR("Can not get stmt of cursor:[%lu]", ul_curr_cursor);
                goto error;
            }
        }
    }

    if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_m) != FR_SUCC) // m
        goto error;

    if (i_m > 0)
    {
        if (ora_mar_skipNBytes_by_len(i_m, p_st_ora_packet) != FR_SUCC) // arrayOfByte
            goto error;
    }

    if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_n) != FR_SUCC) // n
        goto error;
    for (i_loop = 0; i_loop < i_n; i_loop++)
    {
        if (ora_mar_unmarshalKeywordValue(p_st_sess, p_st_ora_packet) == FR_SUCC)
            ora_free((void **) &p_tmp);
        else
            goto error;
    }

    if (p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET)
    {
        if (ora_mar_peekUB1(p_st_ora_packet, &s_tmp) != FR_SUCC) // g
            goto error;
        if (p_st_sess->i_use_special_field == FR_NO)
            p_st_sess->i_ttc8_stmt_resp_rpag = s_tmp <= 0x03 ? FR_YES : FR_NO;
        else if (p_st_sess->i_use_special_field == FR_YES)
        {
            if (s_tmp <= 0x03)
                p_st_sess->i_ttc8_stmt_resp_rpag = FR_YES;
            else
            {
                if (bytebuff_peek_long(p_st_ora_packet->p_st_packet, 4, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                    goto error;
                if (uint64_tmp == 0)
                    p_st_sess->i_ttc8_stmt_resp_rpag = FR_YES;
                else
                    p_st_sess->i_ttc8_stmt_resp_rpag = FR_NO;
            }
        }
        if (p_st_sess->i_ttc8_stmt_resp_rpag == FR_NO)
            p_st_sess->i_ttc8_stmt_resp_rpadml = FR_NO;

        ORA_PRINT_ALERT("set i_ttc8_stmt_resp_rpag = %s, i_ttc8_stmt_resp_rpadml = %s\n",
                        p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_rpag == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_rpadml == FR_YES ? "FR_YES" : "FR_NO"));
    }

    if (p_st_sess->i_ttc8_stmt_resp_rpag == FR_YES)
    {
        if (ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &i_g) != FR_SUCC) // g
            goto error;
        if (i_g > 0)
        {
            if (ora_mar_skipNBytes_by_len(i_g, p_st_ora_packet) == FR_SUCC) // arrayOfByte2
                goto error;
        }

        if (p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET)
        {
            if (ora_mar_peekUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
                goto error;
            if (s_tmp == 0x04)
            {
                if (p_st_stmt->i_is_dml == FR_YES)
                    p_st_sess->i_ttc8_stmt_resp_rpadml = FR_NO;
            }
            else
            {
                if (p_st_stmt->i_is_dml == FR_NO)
                    goto error;

                int i_pos = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
                if (ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &i_p) != FR_SUCC) // p
                    goto error;
                for (i_loop = 0; i_loop < i_p; i_loop++)
                {
                    if (ora_mar_unmarshalSB8(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // arrayOfInt2
                        break;
                }
                if (i_loop == i_p - 1)
                {
                    if (ora_mar_peekUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
                        goto error;
                    if (s_tmp == 0x04)
                        p_st_sess->i_ttc8_stmt_resp_rpadml = FR_YES;
                    else
                        p_st_sess->i_ttc8_stmt_resp_rpadml = FR_NO;
                }
                else
                    p_st_sess->i_ttc8_stmt_resp_rpadml = FR_NO;
                if (bytebuff_setPosition(p_st_ora_packet->p_st_packet, i_pos) != FR_SUCC)
                    goto error;
            }

            ORA_PRINT_ALERT("set i_ttc8_stmt_resp_rpadml = %s\n",
                            p_st_sess->i_ttc8_stmt_resp_rpadml == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_rpadml == FR_YES ? "FR_YES" : "FR_NO"));
        }

        if (p_st_stmt->i_is_dml == FR_YES && p_st_sess->i_ttc8_stmt_resp_rpadml == FR_YES)
        {
            if (ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &i_p) != FR_SUCC) // p
                goto error;
            ORA_PRINT_INFO("unmarshal p\n");

            p_st_curr_sess->ui_batch_count = (unsigned int) i_p;
            ORA_PRINT_WARN("ui_batch_count:[%u]\n", p_st_curr_sess->ui_batch_count);

#ifdef ORA_CHK_BATCH_COUNT
            if (p_st_curr_sess->ui_batch_count > APM_ORA_BATCH_COUNT_THRESHOLD)
            {
                ORA_PRINT_EMERG("ui_batch_count[%u] is great than APM_ORA_BATCH_COUNT_THRESHOLD:[%d]\n", p_st_curr_sess->ui_batch_count, APM_ORA_BATCH_COUNT_THRESHOLD);
                goto error;
            }
#endif

            if (p_st_curr_sess->ui_batch_count > 0 && (p_st_curr_sess->p_ll_rows = (long long *) frmalloc(p_st_curr_sess->ui_batch_count * sizeof(long long))) == NULL)
            {
                ORA_MALLOCK_ERR;
                goto error;
            }

            for (i_loop = 0; i_loop < (int) p_st_curr_sess->ui_batch_count; i_loop++)
            {
                // batch时返回的影响行数
                if (ora_mar_unmarshalSB8(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // arrayOfInt2
                    goto error;
                ORA_PRINT_WARN("rows changed:[%lld]\n", ll_tmp);
                p_st_curr_sess->p_ll_rows[i_loop] = ll_tmp;
            }
        }
    }

    // 记录当前解析完的位置点
    p_st_ora_packet->i_analyze_position = bytebuff_getPosition(p_st_ora_packet->p_st_packet);
    p_st_ora_packet->i_rpa_processed_flag = FR_YES;

    return FR_SUCC;
error:
    p_st_sess->i_ttc8_stmt_resp_rpag = i_ttc8_stmt_resp_rpag_old;
    p_st_sess->i_ttc8_stmt_resp_rpadml = i_ttc8_stmt_resp_rpadml_old;
    ora_free((void **) &p_arr_int);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  RPC -> readRXH
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_read_RXH(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    if (ora_ttc8_tti_rxh_unmarshalV10(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
        return FR_FAIL;

    // 记录当前解析完的位置点
    p_st_ora_packet->i_analyze_position = bytebuff_getPosition(p_st_ora_packet->p_st_packet);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  RPC -> readDCB
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_oall8_read_DCB(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    Sql_statement *p_st_stmt = NULL;

    if ((p_st_stmt = ora_get_current_stmt(p_st_conn)) == NULL)
        goto error;

    if (ora_ttc8_tti_dcb_receive(p_st_conn, p_st_sess, p_st_ora_packet, p_st_stmt) != FR_SUCC)
        return FR_FAIL;

    // 记录当前解析完的位置点
    p_st_ora_packet->i_analyze_position = bytebuff_getPosition(p_st_ora_packet->p_st_packet);

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  设置RPC函数调用指针
*  ARGS     :  *p_st_ora_rpc_recv                   (函数指针结构体)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void ora_ttc8_oall8_set_rpc_func(Ora_rpc_recv *p_st_ora_rpc_recv)
{
    p_st_ora_rpc_recv->read_BVC = &ora_ttc8_oall8_read_BVC;
    p_st_ora_rpc_recv->read_IOV = &ora_ttc8_oall8_read_IOV;
    p_st_ora_rpc_recv->read_DCB = &ora_ttc8_oall8_read_DCB;
    p_st_ora_rpc_recv->read_RXH = &ora_ttc8_oall8_read_RXH;
    p_st_ora_rpc_recv->read_RXD = &ora_ttc8_oall8_read_RXD;
    p_st_ora_rpc_recv->read_RPA = &ora_ttc8_oall8_read_RPA;
    return;
}

int ora_ttc8_analyze_resp(Conntrack *p_st_conn
                        , L7session_ora *p_st_sess
                        , L7_ora_packet *p_st_ora_packet
                        , int i_sess_type)
{
    ORA_PRINT_FATAL("enter ora_ttc8_analyze_resp\n");
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    short s_ret_code = 0;                                // return code
    int i_has_dcb = FR_NO;

    int i_ttc8_stmt_resp_udskpos_old = p_st_sess->i_ttc8_stmt_resp_udskpos;
    int i_ttc8_stmt_resp_udsflg_old = p_st_sess->i_ttc8_stmt_resp_udsflg;
    int i_ttc8_stmt_resp_dcbkm_old = p_st_sess->i_ttc8_stmt_resp_dcbkm;
    int i_ttc8_stmt_resp_dcbni1_old = p_st_sess->i_ttc8_stmt_resp_dcbni1;
    int i_ttc8_stmt_resp_dcbab2_old = p_st_sess->i_ttc8_stmt_resp_dcbab2;
    int i_ttc8_stmt_resp_rpag_old = p_st_sess->i_ttc8_stmt_resp_rpag;
//    int i_ttc8_stmt_resp_rpadml_old = p_st_sess->i_ttc8_stmt_resp_rpadml;
    int i_ttc8_stmt_resp_oereocs_old = p_st_sess->i_ttc8_stmt_resp_oereocs;
    int i_ttc8_stmt_resp_oerendseq_old = p_st_sess->i_ttc8_stmt_resp_oerendseq;
    int i_ttc8_stmt_resp_oeraij_old = p_st_sess->i_ttc8_stmt_resp_oeraij;
    int i_ttc8_stmt_resp_oci_oerskip8_old = p_st_sess->i_ttc8_stmt_resp_oci_oerskip8;
//    int i_ttc8_stmt_resp_oci_oerskip6_old = p_st_sess->i_ttc8_stmt_resp_oci_oerskip6;

    p_st_curr_sess->i_rpa_processed_flag = FR_NO;
    p_st_curr_sess->i_iov_processed_flag = FR_NO;
    p_st_curr_sess->i_cursor_inrpa = 0;

    while (1)
    {
        if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_ret_code) == FR_FAIL)
            goto error;

        // 第一个s_ret_code得是16
        if (i_has_dcb == FR_NO && s_ret_code != 16)
        {
            ORA_PRINT_EMERG("first retCode:[%d] is not 16\n", s_ret_code);
            goto error;
        }

        switch (s_ret_code)
        {
            case 16:
                i_has_dcb = FR_YES;
                if (ora_ttc8_oall8_read_DCB(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case 6:
                ORA_PRINT_INFO("call 6  read_RXH\n");
                p_st_curr_sess->i_bvc_found = FR_NO;
                p_st_curr_sess->i_bvc_num = 0;
                if (ora_ttc8_oall8_read_RXH(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case 7:
                ORA_PRINT_INFO("call 7  read_RXD\n");
                if (ora_ttc8_oall8_read_RXD(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case 21:
                ORA_PRINT_INFO("call 21 read_BVC\n");
                if (ora_ttc8_oall8_read_BVC(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                break;

            case 8:
                ORA_PRINT_INFO("call 8  read_RPA\n");
                if (p_st_curr_sess->i_rpa_processed_flag == FR_YES)
                    goto error;
                if (ora_ttc8_oall8_read_RPA(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
                p_st_curr_sess->i_rpa_processed_flag = FR_YES;
                break;

            case 4:
                ORA_PRINT_INFO("call 4  oer\n");
                if (ora_ttc8_tti_oer_unmarshal(p_st_conn, p_st_sess, p_st_ora_packet, APM_ORA_SESS_IS_TEST, NULL) == FR_FAIL)
                    goto error;
                goto success;

            case 11:
            case 12:
            case 14:
            case 23:
            case 19:
            case 27:
            case 9:
            case 15:
            case 13:
                goto error;

            default:
                ORA_PRINT_EMERG("unknown returnFlag:[%d]\n", s_ret_code);
                goto error;
        }
    }

success:
    if (p_st_sess->i_use_special_field == FR_NO) // jdbc
    {
        if ((i_ttc8_stmt_resp_udskpos_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_udsflg_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_dcbkm_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_dcbni1_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_dcbab2_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_rpag_old == APM_ORA_FLAG_UNSET ||
//             i_ttc8_stmt_resp_rpadml_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_oereocs_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_oerendseq_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_oeraij_old == APM_ORA_FLAG_UNSET) &&
            p_st_sess->i_ttc8_stmt_resp_udskpos != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_udsflg != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_dcbkm != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_dcbni1 != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_dcbab2 != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_rpag != APM_ORA_FLAG_UNSET &&
//            p_st_sess->i_ttc8_stmt_resp_rpadml != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_oereocs != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_oerendseq != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_oeraij != APM_ORA_FLAG_UNSET)
        {
            ORA_PRINT_WARN("analyze stmt reponse successfully, session id:[%s]\n", p_st_session->arr_session_id);
            ORA_FRLOG_ERROR("analyze stmt reponse successfully, session id:[%s]", p_st_session->arr_session_id);
            p_st_sess->ull_error_nums = 0LL;
            p_st_sess->i_ttc8_long_analyze_succ = FR_YES;
            p_st_ora_packet->i_analyze_position = 0;
            p_st_curr_sess->i_rpa_processed_flag = FR_NO;
            p_st_curr_sess->i_iov_processed_flag = FR_NO;
        }
    }
    else
    {
        ORA_PRINT_ALERT("leave ora_ttc8_analyze_resp\n"
                                "i_ttc8_stmt_resp_udskpos = %s\n"
                                "i_ttc8_stmt_resp_udsflg = %s\n"
                                "i_ttc8_stmt_resp_dcbkm = %s\n"
                                "i_ttc8_stmt_resp_dcbni1 = %s\n"
                                "i_ttc8_stmt_resp_dcbab2 = %s\n"
                                "i_ttc8_stmt_resp_rpag = %s\n"
                                "i_ttc8_stmt_resp_oereocs = %s\n"
                                "i_ttc8_stmt_resp_oerendseq = %s\n"
                                "i_ttc8_stmt_resp_oci_oerskip8 = %s\n"
                                "i_ttc8_stmt_resp_oci_oerskip6 = %s\n",
                        p_st_sess->i_ttc8_stmt_resp_udskpos == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_udskpos == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_udsflg == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_udsflg == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_dcbkm == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_dcbni1 == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_dcbab2 == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_dcbab2 == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_rpag == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_rpag == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_oereocs == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_oereocs == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_oerendseq == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_oerendseq == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_oci_oerskip8 == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_oci_oerskip8 == FR_YES ? "FR_YES" : "FR_NO"),
                        p_st_sess->i_ttc8_stmt_resp_oci_oerskip6 == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_oci_oerskip6 == FR_YES ? "FR_YES" : "FR_NO"));

        if ((i_ttc8_stmt_resp_udskpos_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_udsflg_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_dcbkm_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_dcbni1_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_dcbab2_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_rpag_old == APM_ORA_FLAG_UNSET ||
//             i_ttc8_stmt_resp_rpadml_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_oereocs_old == APM_ORA_FLAG_UNSET ||
             i_ttc8_stmt_resp_oerendseq_old == APM_ORA_FLAG_UNSET ||
            i_ttc8_stmt_resp_oci_oerskip8_old == APM_ORA_FLAG_UNSET) &&
//            i_ttc8_stmt_resp_oci_oerskip6_old == APM_ORA_FLAG_UNSET) &&
            p_st_sess->i_ttc8_stmt_resp_udskpos != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_udsflg != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_dcbkm != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_dcbni1 != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_dcbab2 != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_rpag != APM_ORA_FLAG_UNSET &&
//            p_st_sess->i_ttc8_stmt_resp_rpadml != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_oereocs != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_oerendseq != APM_ORA_FLAG_UNSET &&
            p_st_sess->i_ttc8_stmt_resp_oci_oerskip8 != APM_ORA_FLAG_UNSET)
//            p_st_sess->i_ttc8_stmt_resp_oci_oerskip6 != APM_ORA_FLAG_UNSET)
        {
            ORA_PRINT_WARN("analyze stmt reponse successfully, session id:[%s]\n", p_st_session->arr_session_id);
            ORA_FRLOG_ERROR("analyze stmt reponse successfully, session id:[%s]", p_st_session->arr_session_id);
            p_st_sess->ull_error_nums = 0LL;
            p_st_sess->i_ttc8_long_analyze_succ = FR_YES;
            p_st_ora_packet->i_analyze_position = 0;
            p_st_curr_sess->i_rpa_processed_flag = FR_NO;
            p_st_curr_sess->i_iov_processed_flag = FR_NO;
        }
    }

    return FR_SUCC;
error:
    return FR_FAIL;
}
